2

我知道下面示例中的编译器将执行 function First::fun(),因为 Argument-Dependent name Lookup (ADL)/Koenig lookup 并且为了执行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()仍然可以通过在全局名称空间前加上前缀来调用全局名称:::fun(First::FIRST);

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

4

1 回答 1

5

为什么编译器fun()在模棱两可的调用中不喜欢全局?

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

除了通常的非限定名称查找所考虑的范围和名称空间之外,还会在其参数的名称空间中查找这些函数名称。

于 2020-11-13T15:27:26.043 回答