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

时间:2013-12-04 12:40:02

标签: c++ overloading

代码:

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

3 个答案:

答案 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<<,因此没有歧义。