那里发生了什么?
#include <functional> namespace A { struct Class { }; } bool operator<(const A::Class& a,const A::Class& b) { return false; } int main() { std::less<A::Class>()(A::Class(),A::Class()); return 0; }
这是编译好的.但如果我使用
#include <set>
我有错误:
g++ test.cc -o test In file included from /usr/lib/gcc/x86_64-pc-linux-gnu/4.5.2/include/g++-v4/bits/stl_tree.h:64:0,from /usr/lib/gcc/x86_64-pc-linux-gnu/4.5.2/include/g++-v4/set:60,from lookup.cc:1: /usr/lib/gcc/x86_64-pc-linux-gnu/4.5.2/include/g++-v4/bits/stl_function.h: In member function 'bool std::less<_Tp>::operator()(const _Tp&,const _Tp&) const [with _Tp = A::Class]': test.cc:15:49: instantiated from here /usr/lib/gcc/x86_64-pc-linux-gnu/4.5.2/include/g++-v4/bits/stl_function.h:230:22: error: no match for 'operator<' in '__x < __y' make: *** [test] Error 1
解决方法
查找失败的原因是该集合引入一个运算符<对于std :: set在std命名空间中隐藏所有其他全局运算符< lt. 查找<在std :: less的实例化中,std命名空间内的范围内发生.任何操作者的唯一方法如果ADL开始采取行动,并且只发生在最近的封闭命名空间,std命名空间之外将变得可见. 不包括< set>,没有运算符<在std命名空间中引入(并且这可能是实现依赖的)隐藏全局运算符<因此非ADL查找规则仍然可以找到全局运算符这需要A :: Class. 更正:正如@JohannesSchaub指出的那样,如果操作者的声明在<功能>之前发生(其中std :: less定义)被首先包含.就这样,通过非限定ID的函数调用的唯一重载应该在模板定义内的非ADL查找中可见,在定义点是可见的.在定义点和实例点之间引入的定义只能在ADL查找时可见. (在诸如x
函数的运算符<中的表达式中,被搜索,并且这是一个特定形式的不合格的id.) 就这样,过载运算符<不应被视为有或没有<="" set="">
的候选人.包括,虽然查找规则中的这些角落并不总是被所有编译器正确处理.
函数的运算符<中的表达式中,并且这是一个特定形式的不合格的id.)>