Reputation: 5054
I just created a really little project I thought I could do in no time (it's about basic delegates) when I came across an interesting compiler bug that I couldn't track down. Here is the simplified version of the code:
class NoComp {
};
class Comp {
bool operator==(const Comp& other)
{ std::cout << "Working!" << std::endl; return true;}
};
struct Test {
template<typename T>
Test(T&& obj) {}
bool operator==(const Test& other);
};
int main()
{
Test a(Comp());
Test b(NoComp());
a.operator ==(b);
}
This produces the following compiler error when compiled with g++ version 4.8.3 20140911 (Red Hat 4.8.3-7) (GCC)
found here:
main.cpp: In function 'int main()':
main.cpp:22:13: error: request for member 'operator==' in 'a', which is
of non-class type 'Test(Comp (*)())'
a.operator ==(b);
I can't figure out what that error means and why it even exists. What happens there, is it a bug or covered by the standard? How can I dodge that, if I can?
Upvotes: 0
Views: 79
Reputation: 56577
You have what is called the most vexing parse.
The lines
Test a(Comp());
Test b(NoComp());
do not declare variables, but two functions a
and b
, taking a pointer-to-function that returs Comp
(NoComp
) and takes no parameters.
If you have access to C++11, use the list-initialization, i.e.
Test a{Comp()};
Test b{NoComp()};
or if you don't, use double parenthesis
Test a((Comp()));
Test b((NoComp()));
Upvotes: 3
Reputation: 61009
Test a(Comp());
Test b(NoComp());
This declares two functions called a
and b
. The first one has one parameter of type Comp(*)()
and a return type of Test
, and the second one takes a NoComp(*)()
and also returns a Test
. Comp()
is a function type and, as all parameters of function type, adjusted to a pointer-to-function type. Same goes for NoComp()
.
Use double parentheses:
Test a((Comp()));
Test b((NoComp()));
Or list-initialization as of C++11.
Upvotes: 7