Когда явное определение экземпляра шаблона предшествует явному объявлению, GCC и clang расходятся во мнениях.

См. следующий код:

#include <vector>

template class std::vector<int>;
extern template class std::vector<int>;

int main() {}

В то время как GCC 5.2 компилируется нормально, clang 3.6 выдает следующее сообщение об ошибке:

main.cpp:4:28: error: explicit instantiation declaration (with 'extern') follows explicit instantiation definition (without 'extern')
extern template class std::vector<int>
                           ^
main.cpp:3:21: note: explicit instantiation definition is here
template class std::vector<int>
                    ^
1 error generated.

Тем не менее, для следующего кода

template <typename T>
void f() {}

template void f<int>();
extern template void f<int>();

int main() {}

И GCC, и clang выдали ошибку. Сообщение для GCC

main.cpp:5:29: error: duplicate explicit instantiation of 'void f() [with T = int]' [-fpermissive]
 extern template void f<int>();

и один для clang

main.cpp:5:22: error: explicit instantiation declaration (with 'extern') follows explicit instantiation definition (without 'extern')
extern template void f<int>();
                     ^
main.cpp:4:15: note: explicit instantiation definition is here
template void f<int>();
              ^
1 error generated.

Что происходит с двумя парнями? Запрещает ли стандарт явному объявлению создания экземпляра шаблона предшествовать явному определению? Это не имеет большого смысла для меня. В конце концов, какой вред может быть в том, чтобы сначала определить, а затем объявить? Просто подумайте о случае с нешаблонными функциями.


person Lingxi    schedule 02.10.2015    source источник


Ответы (1)


Из [temp.explicit] / 11

Если сущность является предметом как явного объявления инстанцирования, так и определения явного воплощения в одной и той же единице перевода, определение должно следовать за объявлением.

GCC также должен выдавать ошибку для первого примера.

Связанная ошибка из 2008 года, у GCC, похоже, проблемы с обнаружением ошибки с классами. , следующее также пропущено

template <typename T> class f {};

template class f<int>;
extern template class f<int>;

int main() {}
person user657267    schedule 02.10.2015