为什么 ADL 不能使用命名空间外定义的函数?

Why doesn't ADL work with functions defined outside of a namespace?

我知道下面示例中的编译器将执行函数 First::fun(),因为参数依赖名称查找 (ADL)/Koenig 查找并且为了执行 Second::fun() 这需要在 main 函数中被显式调用。

#include <iostream>
using namespace std;

namespace First
{
    enum Enum
    {
        FIRST
    };

    void fun(First::Enum symbol)
    {
        cout << "First fun\n";
    }
}

namespace Second
{
    void fun(First::Enum symbol)
    {
        cout << "Second fun\n";
    }
}

int main()
{
    fun(First::FIRST);  // Calls First::fun()
}

然而,当在命名空间之外添加另一个函数 fun()(见下面的代码)并在没有前缀命名空间的情况下调用 fun() 时,编译器会给出歧义错误。命名空间内的函数仍然可以通过显式命名空间前缀来调用,但是 fun() 是不可达的。当显式调用 none 时,为什么编译器不喜欢命名空间之外的函数?是否有特定原因可以避免这种行为?

// ^ Namespaces are still here

fun(First::Enum symbol)
{
    cout << "No namespace fun\n";
}    

int main()
{
    fun(First::FIRST);  // Doesn't compile: ambiguity!
}

编辑

正如 Yksisarvinen 正确指出的那样,全局 fun() 仍然可以通过在全局命名空间前加上前缀来调用:::fun(First::FIRST);.

然而,这仍然给我留下了一个问题:为什么编译器在模棱两可的调用中不喜欢全局 fun()

Why doesn't the compiler prefer the global fun() in the ambiguous call?

全局 fununqualified name lookup, and First::fun is found by ADL 找到,两者都放在重载集中并且重载解析不能 select 一个。

These function names are looked up in the namespaces of their arguments in addition to the scopes and namespaces considered by the usual unqualified name lookup.