Следующий кодНеоднозначность перегрузки с массивом передается как указатель
#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*)
Почему это неоднозначное сейчас? Я думал, что массив всегда был просто указателем, поэтому я не вижу разницы.
Edit:
Я просто понял, что весь код, который я была плохая идея, чтобы начать с: Как только вы добавляете элементы данных в классы и доступ к ним в foo
функции вы столкнетесь с проблемами , как объясняется here, так как функция foo(B*)
не имеет способа узнать, что она фактически имеет дело с объектами C
, которые потенциально занимают больше места в памяти. Так что не делай этого!
Тем не менее меня все еще интересует, почему компилятор жалуется на двусмысленность здесь, так как я действительно не вижу проблемы с , что здесь.
vs2008, я не могу воспроизвести ошибку - и последний тестовый пример печатает «B». – Gombat
Работает ли foo (& c [0])? – Gombat
[Массивы не указатели] (https://stackoverflow.com/questions/1641957/is-array-name-a-pointer-in-c). Откуда взялась эта идея? Кроме того, арифметика указателя, необходимая для доступа к массиву, не будет работать, если вы нарисуете массив 'C' на указатель на' B' (или 'A', если на то пошло); как только 'C' содержит некоторые члены данных,' b [1] 'не даст вам действительный объект, потому что' sizeof (B)! = sizeof (C) '(и это неопределенное поведение до этого также). – Wintermute