C2070 - недопустимый размер операнда
Следующий код выглядит хорошо для меня:
#include <stdio.h>
template <typename T>
struct A
{
static float m_kA[];
};
template <typename T>
float A<T>::m_kA[] = {1.0f, 2.0f, 3.0f};
int main()
{
printf("%d\n",
sizeof(A<unsigned int>::m_kA) /
sizeof(A<unsigned int>::m_kA[0]));
return 0;
}
Но когда я компилирую с VC9, я получаю следующую ошибку
error C2070: 'float []': illegal sizeof operand
Я ожидаю, что этот код скомпилируется. Я что-то пропустил? Кто-нибудь знает способ исправить это странное поведение (обратите внимание, что то же самое без шаблона компилируется нормально и выводит 3).
Обратите внимание, что удаление шаблона не вариант, я сделал этот пример, чтобы воспроизвести проблему, с которой я столкнулся в коде, где мне нужен тип, содержащий массив, чтобы быть шаблоном.
Спасибо
2 ответа
он прекрасно компилируется с G++.
Насколько я вижу, это может быть связано с этой ошибкой:
Это хорошо определено. Обратите внимание, что в определении класса m_kA
объявлен с типом float[]
, который является неполным типом и не может использоваться в тандеме с sizeof
, В определении m_kA
, объявлено, чтобы иметь тип float[3]
после чего можно использовать sizeof
, (8.3.4 определяет смысл объявлений массива.)
Начиная с 3.4.6 директивы Using и псевдонимы пространства имен [basic.lookup.udir]:
10 После всех корректировок типов (во время которых typedefs (7.1.3) заменяются их определениями) типы, указанные во всех объявлениях, ссылающихся на данную переменную или функцию, должны быть идентичными, за исключением того, что объявления для объекта массива могут указывать типы массива которые отличаются наличием или отсутствием привязки основного массива (8.3.4). Нарушение этого правила для идентификации типа не требует диагностики.
Начиная с версии 3.9.2 Составные типы [basic.compound]:
6 [...] Объявленный тип объекта массива может быть массивом неизвестного размера и поэтому может быть неполным в одной точке единицы преобразования и завершаться позже; типы массивов в этих двух точках ("массив неизвестной границы T" и "массив N T") - это разные типы. [...]
Обходной путь для ваших проблем компилятора должен был бы объявить m_kA
с полным типом прямо. Также может быть полезен другой статический элемент, содержащий размер.
[Я цитирую C++11, но, насколько мне известно, C++03 следовал тем же правилам. ]