当一个定义位于命名空间中时不明确的函数调用

Ambiguous Function Call when One Definition is in a Namespace

本文关键字:命名空间 不明确 函数调用 定义 一个      更新时间:2023-10-16

我有一个简单的程序,包含以下代码:

namespace nam
{
    struct S{};
    void f(S *){}
}
void f(nam::S *){}
int main()
{
    nam::f(nullptr);
    nam::S s;
    f(&s);
    return 0;
}

我希望这将编译良好,因为我第二次调用f而不指定命名空间nam。 但是,在编译代码时,我收到此错误:

$ g++ main.cpp -std=c++11 -Wall -Wextra
main.cpp: In function ‘int main()’:
main.cpp:14:9: error: call of overloaded ‘f(nam::S*)’ is ambiguous
     f(&s);
         ^
main.cpp:7:6: note: candidate: void f(nam::S*)
 void f(nam::S *){}
      ^
main.cpp:4:10: note: candidate: void nam::f(nam::S*)
     void f(S *){}

编译器和版本:

$ gcc --version
gcc (Debian 5.3.1-14) 5.3.1 20160409

使用不同的编译器尝试此操作后,将返回类似的错误。 这似乎是C++的一个定义部分。 我在互联网上找不到任何地方说调用带有 namespace nam 结构作为参数的函数实际上意味着using namespace nam;并且需要::f来消除歧义。 我对此有两个问题:

  1. 这在C++标准中在哪里定义?
  2. 这种行为有充分的理由吗?

就个人而言,我喜欢避免using namespace x;和类似的事情。 我希望编译器在我不指定命名空间时给我一个错误。 此行为会阻止编译器执行此操作,这意味着我的代码在某些地方不一致,因为在调用未在任何地方全局声明的函数(如f)时,我偶尔会忘记指定命名空间。

f(nam::S*) 的实现在 'nam' 的命名空间之外

改变:

void f(nam::S *){}

自:

void nam::f(nam::S *){}

(或者只是移动封闭的命名空间括号)一切都应该没问题。

如果你在当前命名空间中对 f(&s) 的调用是有意的,那么你需要通过将函数调用更改为

::f(&s)

正如评论中所说,这是由于依赖于参数的查找。 我想现在我必须弄清楚我是否要始终在我的代码中指定命名空间,这将使它变得不必要,或者永远不指定它。