这是一个编译器错误?
template <typename T>
T& operator++(T& t)
{
return t;
}
namespace asdf {
enum Foo { };
enum Bar { };
Foo& operator++(Foo& foo);
void fun()
{
Bar bar;
++bar;
}
} // end namespace asdf
int main()
{
return 0;
}
在GCC 4.7错误信息是:
error: no match for 'operator++' in '++bar'
note: candidate is:
note: asdf::Foo& asdf::operator++(asdf::Foo&)
note: no known conversion for argument 1 from 'asdf::Bar' to 'asdf::Foo&'
如果您注释掉它编译:
Foo& operator++(Foo& foo);
不,这是不是一个错误。 也有认为运营商的三个平行组。 会员,非会员运营,并内建命令。
非成员的人通过正常的不合格+ ADL查找抬头,忽略所有类的成员函数。 因此,全球运营商通过词法更接近一(和居间成员函数不会隐藏在其他非成员)隐藏。
需要注意的是重载的名称查找1 后进行; 你的情况名operator++
被发现,但没有适当的过载。
如果酒吧已被全局声明,和/或其他运营商的命名空间ASDF,ADL(在前者的情况下)或普通不合格查找(在后一种情况下),会拖累的运营商。
1: Overload resolution (...) takes place after name lookup has succeeded.
(C ++标准)
不,这不是一个编译器错误。
有迹象表明,得到的表达进行了两个名字-查找++bar
。
- 常规名称查找搜索封闭范围和命名空间,直到找到第一次出现的
operator++
。 因此,全局命名空间最后被搜索该搜索作品里面出来。 当寻找操作功能,成员函数分别处理(不此搜索停止)。 - 从属参数的查找踢下,检索附加的类和命名空间,但只有那些与所述函数(的参数
operator++
在这种情况下)。
在这个问题的例子,正常查找发现asdf::operator++
和停止查找。
该参数相关查询只增加了asdf
命名空间的地方进行搜索,因为这是相关联的命名空间enum Bar
。 出于这个原因,全球operator++
无法找到。
你可以使全球operator++
与命名空间using声明中找到asdf
。
只有重载适用于在同一范围内定义的名称。 一旦编译器发现匹配的名称不看在外部范围,即使它找到的名称适用于一些不能使用。 这无关与运营商; 如果代码,它使用运营商以同样的方式使用的函数名称++它会得到同样的错误。 例如:
void f(int);
struct C {
void f(const C&);
void g() {
f(3); // error: f(const C&) can't be called with argument 3
};