为什么GCC允许在不使用其命名空间的情况下调用此函数?

Cal*_*ius 17 c++ scope namespaces

可能重复:
为什么C++参数范围会影响命名空间中的函数查找?

今天我经历了这种奇怪的行为.我可以先调用strangeFn using namespace Strange,但不允许调用strangeFn2为什么?

namespace Strange
{
    struct X
    {
    };
    void strangeFn(X&) {}
    void strangeFn2(int) {}
}

int main()
{
    Strange::X x;
    strangeFn(x);    // GCC allows calling this function.
    strangeFn2(0);   // Error: strangeFn2 is not declared in this scope.
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

C++编译器如何解决符号的范围?

seh*_*ehe 33

这称为Argument Dependent Lookup(或Koenig Lookup)

基本上,如果无法解析符号,编译器将查看参数的名称空间.

第二个函数调用失败,因为strangeFn2在当前命名空间中不可见,也没有在它的参数类型(int)的命名空间中定义

您可以看到它如何与运算符函数一起使用:

 std::complex<double> c, d;
 c += d; // wouldn't really work without ADL
Run Code Online (Sandbox Code Playgroud)

或无处不在的iostream运营商:

 std::string s("hello world");
 std::cout << s << std::endl; // Hello world would not compile without ADL...
Run Code Online (Sandbox Code Playgroud)

为了好玩,这就是没有ADL(没有using关键字......)的hello世界:

 std::string s("hello world");
 std::operator<<(std::cout, s).operator<<(std::endl); // ugly!
Run Code Online (Sandbox Code Playgroud)

在存在函数模板的情况下,存在具有ADL和重载解析的阴影角点情况,但是我现在将它们置于答案的范围之外.

  • 哇!人们永远不会知道C++. (8认同)
  • 酷,不知道这会影响像“Hello World”这样简单的事情...... (3认同)