提问者:小点点

为什么ADL不能处理在命名空间之外定义的函数?


我知道下面示例中的编译器将执行函数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()是不可访问的。当没有显式调用名称空间时,编译器为什么不喜欢名称空间之外的函数呢?有没有具体的原因避免这种行为?

// ^ Namespaces are still here

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

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

编辑

正如Yksisarvinen理直气壮地指出的,仍然可以通过使用全局名称空间:::fun(first::first);前缀来调用全局fun()

但是,这还是给我留下了一个问题:为什么编译器不喜欢在模棱两可的调用中使用全局的fun()呢?


共1个答案

匿名用户

为什么编译器在不明确的调用中不喜欢全局的fun()呢?

全局fun通过非限定名称查找找到,first::fun通过ADL找到,两者都放在重载集中,重载解析不能选择一个。

除了通常的非限定名称查找所考虑的作用域和名称空间之外,还在它们参数的名称空间中查找这些函数名。