下面的代码
#include <iostream>
using namespace std;
class A {};
class B : public A {};
class C : public B {};
void foo(A *a) {
cout << 'A' << endl;
}
void foo(B *b) {
cout << 'B' << endl;
}
int main() {
C *c = new C[10];
foo(c);
}
编译正常并按预期打印“B”。
但是当我将 main()
函数更改为
int main() {
C c[10];
foo(c);
}
我得到一个编译器错误提示
test_arr.cpp: In function 'int main()':
test_arr.cpp:23:10: error: call of overloaded 'foo(C [10])' is ambiguous
test_arr.cpp:23:10: note: candidates are:
test_arr.cpp:11:6: note: void foo(A*)
test_arr.cpp:15:6: note: void foo(B*)
怎么现在模棱两可了?我认为数组始终只是一个指针,所以我看不出有什么区别。
编辑:
我刚刚意识到我发布的整个代码是一个坏主意:一旦您将数据成员添加到类中并在 foo
函数中访问它们,您就会遇到问题,因为解释 here ,因为 foo(B*)
函数无法知道它实际上是在处理可能占用更多内存空间的 C
对象。所以不要这样做!
尽管如此,我仍然有兴趣了解为什么编译器在这里提示歧义,因为我真的没有看到that这里有问题。
最佳答案
我相信这是一个 gcc 错误。代码在 clang 上编译。
首先,两位候选人都是可行的。来自[转化]:
A standard conversion sequence is a sequence of standard conversions in the following order:
— Zero or one conversion from the following set: lvalue-to-rvalue conversion, array-to-pointer conversion, and function-to-pointer conversion.
— Zero or one conversion from the following set: integral promotions, floating point promotion, integral conversions, floating point conversions, floating-integral conversions, pointer conversions, pointer to member conversions, and boolean conversions.
对 foo
的两次调用都涉及数组到指针的转换(从 C[10]
到 C*
),然后是指针转换(从 C*
到 A*
或 B*
)。这是允许的标准转换。
现在,我们如何对这些转化进行排名?有趣的是,标准中的行完全我们的用例,在 [over.ics.rank] 中:
Two conversion sequences with the same rank are indistinguishable unless one of the following rules applies:
— If class B is derived directly or indirectly from class A and class C is derived directly or indirectly from B,
— conversion of C* to B* is better than conversion of C* to A*
我们有两个相同等级(Conversion)的转换序列,它们都是可行的,但一个被认为比另一个更好。代码应该明确地优先使用 foo(B*)
而不是 foo(A*)
。 c
被声明为一个数组这一事实不应使它产生歧义。
关于c++ - 数组作为指针传递的不明确重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32522701/