using 声明如何在没有 ADL 的情况下减少可用于查找的名称?

How does a using-declaration reduce the names available for lookup without ADL?

#include <iostream>
#include <string>

class X {};

namespace N
{

std::string to_string(X)
{
    return "foo";
}

void foo()
{
    //using std::to_string; // will break the build if uncommented...
    //using N::to_string;   // ...unless this is uncommented as well
    std::cout << to_string(X()) << std::endl;
}

}

int main()
{
    N::foo();
    return 0;
}

要么我偶然发现了我不掌握的众多 C++ 奥秘之一,要么我在这里遗漏了一些明显的东西。

using std::to_string 如何明显地将非限定查找期间可用的名称集减少为仅可通过 ADL 访问的名称集?虽然我可以猜测问题可能是 to_string(X) 是在与 X 不同的命名空间中声明的,但我不禁注意到,如果没有 using std::to_stringN::to_string(X) 可以简单地用于N::foo() 通过使用 "normal",我习惯的直观查找规则。

这不是特定于 using 声明,而是遵循正常的范围规则。当您在函数中引入一个名称时,会在外部作用域中隐藏同名的东西。

您也可以在 foo 中有一个 int to_string; 局部变量。那也会隐藏 N::to_string.