我刚刚创建了一个非常小的项目,当我遇到一个我无法追踪到的有趣的编译器错误时,我认为我可以立即做(它是关于基本代理的)。以下是代码的简化版本:
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);
}
使用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);
我无法弄清楚该错误的含义以及它为何存在。那里发生了什么,它是一个bug还是标准所涵盖的?如果可以的话,我该怎么回避?
答案 0 :(得分:7)
Test a(Comp());
Test b(NoComp());
这声明了两个名为a
和b
的函数。第一个参数的类型为Comp(*)()
,返回类型为Test
,第二个参数为NoComp(*)()
,并返回Test
。 Comp()
是一个函数类型,并且作为函数类型的所有参数,调整为指向函数的类型。同样适用于NoComp()
。
使用双括号:
Test a((Comp()));
Test b((NoComp()));
或者从C ++ 11开始的列表初始化。
答案 1 :(得分:3)
您拥有所谓的most vexing parse。
行
Test a(Comp());
Test b(NoComp());
不要声明变量,而是声明两个函数a
和b
,采用指向函数的指针Comp
(NoComp
)并且不带参数。
如果您可以访问C ++ 11,请使用list-initialization,即
Test a{Comp()};
Test b{NoComp()};
或者如果你不这样做,请使用双括号
Test a((Comp()));
Test b((NoComp()));