Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Weird compiler decision

Tags:

c++

g++

I've got the following code:

enum nums {
  a
};

class cls {
public:
  cls( nums );
};

void function()
{
  cls( a );
}

When I try to compile it with gcc, I get the following error:

test.cpp: In function ‘void function()’:
test.cpp:12:10: error: no matching function for call to ‘cls::cls()’
test.cpp:12:10: note: candidates are:
test.cpp:7:3: note: cls::cls(nums)
test.cpp:7:3: note:   candidate expects 1 argument, 0 provided
test.cpp:5:7: note: cls::cls(const cls&)
test.cpp:5:7: note:   candidate expects 1 argument, 0 provided
make: *** [test] Error 1

If I replace the function with this:

void function()
{
  cls name( a );
}

then everything works. It also works if I use a constructor with two arguments. It does not work if I add "explicit" to the constructor.

I get that gcc is somehow parsing this as defining a variable of type "cls" with the name "a", but I am not familiar with such a syntax for defining variables. To my eyes, this is a statement defining an anonymous temporary variable of type cls, passing "a" is the parameter.

Compiled with gcc 4.6.3.

Any insights?

Thanks, Shachar

like image 891
Shachar Shemesh Avatar asked Dec 01 '22 18:12

Shachar Shemesh


1 Answers

Another example of the most embarassing parse problem. The line:

cls( a );

declares a local variable named a of type cls, which is (or should be) initialized by calling the default constructor. Which doesn't exist, whence the error message.

If you really want to construct a temporary object which will be destructed immediately after, you can remove the ambiguity by putting the entire expression in parentheses:

(cls( a ));

A definition cannot occur in parentheses; an expression can.

like image 194
James Kanze Avatar answered Dec 11 '22 19:12

James Kanze