Вопрос по g++, clang++, forward-declaration, c++, templates – Предварительное объявление класса, используемого в шаблонной функции, не скомпилировано clang ++

12

Вот этот код:

class A;

template <class T>
void fun() {
   A a;
}

class A { 
public: 
   A() {  } 
};

int main() { 
   fun<int>(); 
   return 0;
}

g ++ 4.5 и g ++ 4.7 компилируют это без ошибок. Но clang ++ 3.2 (trunk) выдает эту ошибку:

main.cpp:5:6: error: variable has incomplete type 'A'
   A a;
     ^
main.cpp:1:7: note: forward declaration of 'A'
class A;
      ^

Какой компилятор тогда соответствует стандарту C ++?

Есть ли какие-либо ключи, предоставляемые clang для компиляции такого кода? Sashank
Так как вы пытаетесь создать объект типаA компилятор должен знать его размер, который он не может знать, не увидев полное определение, поэтому clang был бы здесь (но у меня нет ссылки на std). Benjamin Bannier

Ваш Ответ

4   ответа
12

Which compiler is right then according to C++ standard?

Оба верны. Это плохо сформированная программа. Акцент мой:

N3290 14.6¶9
If a type used in a non-dependent name is incomplete at the point at which a template is defined but is complete at the point at which an instantiation is done, and if the completeness of that type affects whether or not the program is well-formed or affects the semantics of the program, the program is ill-formed; no diagnostic is required.

То, что clang ++ и другие компиляторы действительно выдают здесь диагностическую информацию, это хорошая дополнительная функция, но диагностика не обязательна. Этот пункт "программа является плохо сформированной; Диагностика не требуется & quot; дает разработчику компилятора право свободно делать что угодно в таких условиях и при этом быть совместимым.

почему программист даже не сообщает g ++, что что-то не так? должно ли быть так, что оба компилятора верны, но один выполняет свою работу, а второй делает что-то совсем другое? scdmb
Намерение состоит в том, чтобы разрешить ленивую обработку шаблона. Стандарт позволяет реализациям откладывать подробный анализ до того момента, когда создается экземпляр шаблона. Учебный классA известен в момент создания, поэтому он компилируется. Это все еще плохо сформировано, потому что другой файл мог#include определите свой шаблон, определите совершенно другой классAи создать другойfun<int>(), Это не удалось бы связать, потому что это нарушает одно определение правила (даже если вы указалиfun какinline).
1

clang++ использует правильное поведение, это описано в разделе4.6/9 стандарта (n1905).


Templates 14.6/9 Name resolution

If a name does not depend on a template-parameter (as defined in 14.6.2), a declaration (or set of declarations) for that name shall be in scope at the point where the name appears in the template definition; the name is bound to the declaration (or declarations) found at that point and this binding is not affected by declarations that are visible at the point of instantiation.


Проще говоря, если имяnot в зависимости от шаблона-параметра он должен находиться в области видимости определения; поэтому вам нужно определитьA перед вашим определениемtemplate<typename T> void fun ().

Error: User Rate Limit Exceeded
0

Компилятору Comeau это тоже не нравится:

"ComeauTest.c", line 5: error: incomplete type is not allowed
     A a;
       ^

Однако мои попытки найти главу и стих в стандарте C ++ оказались безрезультатными. Он кажется скрытым между линиями и взаимодействиями «точки инстанции», «разрешения имен». Пункты 14.6 / 8 и 14.6 / 9 стандарта 2003 года представляются актуальными.

У меня нет под рукой спецификации, но я знаю, что было добавлено правило (в качестве разрешения DR), чтобы сделать его код некорректным; Диагностика не требуется & quot; когда-нибудь после с ++ 98 или с ++ 03. это находится в параграфе, который говорит о плохо сформированных определениях шаблона.
5

Clang это правильно, насколько я знаю. В свое удовольствие вы не знаете размер A, и, поскольку вы выделяете A, вам нужно знать его размер. На мой взгляд, gcc - это способ простить здесь.

Error: User Rate Limit Exceeded

Похожие вопросы