重载函数的调用是不明确的(两个函数在不同的范围内)

call of overloaded function is ambiguous (two function in different scope)

本文关键字:函数 两个 范围内 调用 不明确 重载      更新时间:2023-10-16

code:

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);

当你这样做时

using asd::f;

你告诉编译器"当我在当前范围内使用符号f时,我的意思实际上是asd::f"。这就是它起作用的原因。

至于第一种情况,这是因为编译器在instance类型(即asd(以及全局范围内查找。它称为参数相关查找。

为什么编译器在命名空间 ASD 的作用域中搜索函数"F"?

依赖于参数的查找。参数类型 A 的范围为 asd ,因此命名空间也会搜索合适的重载。

为什么这叫重载?这是两个不同的函数。

这正是重载的意思:两个名称相同但作用域不同的函数,或者采用不同的参数。

这种情况和我这样做的时候一样吗?

是的,它可能意味着两者之一;但是由于没有::operator<<,所以没有歧义。

C++执行参数相关查找。这意味着,如果您有一个函数的特定类类型的参数,那么为了查找该函数,编译器将在包含参数类型的命名空间中查找函数名称。

在下面的代码中,您已将实例指定为 class A 的变量,该变量是命名空间asd

int main() {
    asd::A instance;
    f(instance);
    return 0;
}

因此,它也将在asd命名空间中查找f。要解决此问题,请使用: ::f(instance);用于在全局命名空间中调用fasd命名空间中调用asd::f(instance);

这称为 koenig 查找。如果您想了解更多信息,请转到此链接。