Объявленный заранее тип и «не относящийся к классу тип, который уже был объявлен как тип класса» - PullRequest
6 голосов
/ 13 мая 2011

У меня проблема со следующим кодом:

  template <typename T>
  void foo(struct bar & b);
  struct bar {};
  int main(){}

Он успешно компилируется в GCC, но не работает в MSVC (2008) со следующей ошибкой:

C2990: 'bar' : non-class type as already been declared as a class type

Код неправильный или это ошибка в MSVC?

Это работает, если я добавлю struct bar; до определения шаблона.

Ответы [ 5 ]

3 голосов
/ 25 мая 2011

И у нас есть победитель:

https://connect.microsoft.com/VisualStudio/feedback/details/668430/forward-declared-type-and-non-class-type-as-already-been-declared-as-a-class-type

Спасибо за сообщение об этой проблеме.Это действительно случай несоответствующего поведения в VC ++.Однако простой обходной путь заключается в изменении порядка объявлений, чтобы объявление "struct bar" было известно при обнаружении объявления шаблона.Из-за низкой серьезности этой ошибки и наших приоритетов мы сожалеем, что не можем исправить ошибку в следующей версии компилятора, но рассмотрим ее в будущем выпуске.

С уважением,

Tanveer Gani Visual C ++ Team

3 голосов
/ 13 мая 2011

В большинстве случаев компилятор C (или C ++) работает строго сверху вниз в вашем исходном коде.Поэтому вам нужно предварительное объявление , прежде чем пытаться ссылаться на struct bar, иначе компилятор не будет знать, что он существует.

1 голос
/ 14 мая 2011
0 голосов
/ 13 мая 2011

Это похоже на действительный код. Что бы ни делал MSVC, это выглядит странным несоответствующим поведением, насколько я вижу.

0 голосов
/ 13 мая 2011

Скорее всего, у вас есть struct bar {}; где-то над этим блоком кода (возможно, в заголовочном файле).См. http://msdn.microsoft.com/en-us/library/zfcw8kk9.aspx

Редактировать: Также по ссылке выше:

C2990 также может произойти из-за критического изменения в компиляторе Visual C ++ для Visual C ++2005;теперь компилятор требует, чтобы несколько объявлений для одного и того же типа были идентичны по отношению к спецификации шаблона.

Так как foo является шаблоном, а bar является "объявленным вперед" в fooсписок аргументов, что произойдет, если вы переместитесь на struct bar {}; выше foo?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...