代码:
namespace asd {
class A { };
void f(A &a) { }
}
void f(asd::A &a) { }
int main() {
asd::A instance;
f(instance);
return 0;
}
错误:
D:\>g++ -Wall -std=c++98 -pedantic a.cpp
a.cpp: In function 'int main()':
a.cpp:10:12: error: call of overloaded 'f(asd::A&)' is ambiguous
a.cpp:10:12: note: candidates are:
a.cpp:6:6: note: void f(asd::A&)
a.cpp:3:7: note: void asd::f(asd::A&)
为什么编译器在命名空间asd的范围内搜索函数'f'? 为什么这称为重载?这是两个不同的功能 如果主要功能是这样的话,我会理解错误:
int main() {
using asd::f;
asd::A instance;
f(instance);
return 0;
}
我会得到一个错误......但是我不这样做...
这种情况和我这样做的情况相同吗?
std::cout << str;
// meaning 1:
std::operator<<(std::cout, str);
// meaning 2:
::operator<<(std::cout, str);
答案 0 :(得分:1)
当你这样做时
using asd::f;
你告诉编译器“当我在当前范围内使用符号f
时,我实际上是指asd::f
”。这就是它起作用的原因。
至于第一种情况,这是因为编译器在instance
(即asd
)类型的范围以及全局范围内查找。它被称为Argument Dependent Lookup。
答案 1 :(得分:1)
C ++执行依赖于参数的查找。这意味着如果你有一个函数的特定类类型的参数,那么为了找到该函数,编译器将在包含参数类型的命名空间中查找函数名。
在以下代码中,您已将实例指定为class A
的变量,即名称空间asd
int main() {
asd::A instance;
f(instance);
return 0;
}
因此,它也将在f
命名空间中查找asd
。要解决此问题:
::f(instance);
用于在全局命名空间中调用f
或在asd::f(instance);
命名空间中调用asd
。
这称为 koenig lookup 。如果您想了解更多信息,请转到此link。
答案 2 :(得分:1)
为什么编译器在命名空间asd的范围内搜索函数'f'?
依赖于参数的查找。参数类型A
的作用域为asd
,因此也会搜索名称空间以查找合适的重载。
为什么这称为重载?这是两个不同的功能。
这正是重载意味着:两个具有相同名称但在不同范围内或使用不同参数的函数。
这种情况和我这样做的情况相同吗?
是的,这可能意味着;但由于没有::operator<<
,因此没有歧义。