c++ - 关于 std::less 行为的问题

标签 c++ gcc stl

那里发生了什么?

#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

最佳答案

查找失败的原因是 set介绍一个 operator<对于 std::setstd隐藏所有其他全局的命名空间 operator< .

查找<std::less 的实例化中发生在 std 内的范围内命名空间。任何operator<的唯一方法在std之外如果 ADL 启动,命名空间将变得可见,并且这只会发生在最近的封闭命名空间上。

不包括<set> , 没有 operator<std 中引入(这可能取决于实现)隐藏全局 operator< 的命名空间因此非 ADL 查找规则仍然可以找到全局 operator<需要 A::Class .

更正:正如@JohannesSchaub 指出的那样,只有声明 operator< 时,此分析才是正确的发生在 <functional> 之前(其中定义了 std::less)首先包含在内。事实上,通过 unqualified-id 调用的函数的唯一重载应该对模板定义内的非 ADL 查找可见,这些重载在定义点可见。在定义点和实例化点之间引入的定义应该只对 ADL 查找可见。 (在类似 x < y 的表达式中搜索名为 operator< 的候选函数,这是 unqualified-id 的一种特殊形式。)

就目前而言,重载的 operator<不应被视为有或没有 <set> 的候选人包括,尽管并非所有编译器都能正确处理查找规则中的这些极端情况。

关于c++ - 关于 std::less 行为的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4921741/

相关文章:

c++ - boost asio 错误类别为空

c - GCC编译不同文件夹中的多个文件

c++ - 矢量化是什么意思?

c++ - 将在 STL 集上运行的函数泛化到所有集合

c++ - Container end() 迭代器如何在(例如)Container 大小变化时演变

c++ - 将 lambda 推送到 C++ STL 队列导致段错误

C++ cout 十六进制值?

c++ - char 到 int 的转换 - 这里发生了什么?

c++ - 串行通信协议(protocol)设计问题

assembly - GCC 内联汇编器,混合寄存器大小 (x86)