redefinition of a variable with a different type

You forgot to give your test variable a name, causing test(a); to be a declaration of a variable named a of type test.

In the other cases, since test(1) and test((int)a) cannot be declarations, but must be some kind of call, your compiler will treat that as constructing a temporary object of type test without a name.


This is really tricky:

test(1);

This is a construction of test with argument 1.

int a = 1;
test(a);

The compiler reads this as test a; (instance of test named a – with default construction). That test doesn't even provide a default constructor isn't considered by compiler at this point.

The fix (found by OP):

int a = 1;
test((int)a);

Now, the compiler is explicitly told to read a as expression (but not as identifier).


The syntax of defining variables in C++ is kind of quirky...

When you do

test(1);

you create a temporary object of the test structure. This object will be destructed immediately.

But when you do

test(a);

you don't create a temporary test object, you actually define a variable named a. It's equivalent to

test a;

You can solve this problem by using curly-braces

test{a};

Or by using an explicit expression for the "argument" (like you do with your cast), as such can't be used as variable names. In similar situation where you need to disambiguate between variables and expressions it's common to use the unary + as in

test(+a);

Tags:

C++