当一个定义位于命名空间中时不明确的函数调用
Ambiguous Function Call when One Definition is in a Namespace
我有一个简单的程序,包含以下代码:
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
来消除歧义。 我对此有两个问题:
- 这在C++标准中在哪里定义?
- 这种行为有充分的理由吗?
就个人而言,我喜欢避免using namespace x;
和类似的事情。 我希望编译器在我不指定命名空间时给我一个错误。 此行为会阻止编译器执行此操作,这意味着我的代码在某些地方不一致,因为在调用未在任何地方全局声明的函数(如f
)时,我偶尔会忘记指定命名空间。
f(nam::S*) 的实现在 'nam' 的命名空间之外
改变:
void f(nam::S *){}
自:
void nam::f(nam::S *){}
(或者只是移动封闭的命名空间括号)一切都应该没问题。
如果你在当前命名空间中对 f(&s) 的调用是有意的,那么你需要通过将函数调用更改为
::f(&s)
正如评论中所说,这是由于依赖于参数的查找。 我想现在我必须弄清楚我是否要始终在我的代码中指定命名空间,这将使它变得不必要,或者永远不指定它。
相关文章:
- C++:对不存在的命名空间使用命名空间指令
- 是否可以将函数导入命名空间,但不能导出它?
- 在 C++17 中的命名空间和子命名空间中重载运算符是不明确的
- 命名空间 std:: 不包含可选
- 有没有办法不使用命名空间中的项?
- Visual Studio 无法解决类和命名空间中重载的明确函数
- 转发声明在命名空间中不起作用的替代方法
- 不使用与左右停止工作命名空间 std 的简单比较
- 为什么 std::variant 找不到运算符<() 当与比较类不在同一命名空间中时
- 有没有办法在不使用命名空间 std 或前缀 std:: 的情况下引用 cout?
- 如何为缺少预定义运算符而不扩展命名空间"std"的标准类型定义运算符>> (istream &, ...)?
- C++使用其他命名空间中的符号,而不使它们可从外部访问
- 如何在另一个名称空间内从另一个命名空间内明确专业化功能模板
- 命名空间:不能在没有对象的情况下调用成员函数
- 当一个定义位于命名空间中时不明确的函数调用
- 内联命名空间和不明确的声明
- 操作员在不同命名空间中的不明确重载
- 解决命名空间中不明确的运算符
- 嵌套的命名空间和不明确的符号
- 不明确的引用和命名空间(来自两个外部库的定义冲突)