当一个定义在命名空间中时,模糊函数调用

时间:2016-04-22 02:44:46

标签: c++ function struct namespaces

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

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. 这种行为有充分的理由吗?
  3. 我个人喜欢避免using namespace x;和类似的。我希望编译器在我没有指定命名空间时给出错误。这种行为会阻止编译器这样做,这意味着我的代码在某些地方是不一致的,因为我偶尔会忘记在调用f之类的函数时指定名称空间,而这些函数并不是全局声明的。

2 个答案:

答案 0 :(得分:0)

你对f(nam :: S *)的实现超出了' nam'

的命名空间

变化:

void f(nam::S *){}

为:

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

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

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

来指定
::f(&s)

答案 1 :(得分:0)

正如评论中所说,这是由于依赖于参数的查找。我想现在我现在必须弄明白,如果我想在我的代码中总是指定命名空间,这将使它变得不必要,或者从不指定它。