Reputation: 14977
See the following code:
#include <vector>
template class std::vector<int>;
extern template class std::vector<int>;
int main() {}
While GCC 5.2 compiles fine, clang 3.6 gives the following error message:
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.
Still, for the following code
template <typename T>
void f() {}
template void f<int>();
extern template void f<int>();
int main() {}
Both GCC and clang errored out. The message for GCC is
main.cpp:5:29: error: duplicate explicit instantiation of 'void f() [with T = int]' [-fpermissive]
extern template void f<int>();
and the one for clang is
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.
What's going on with the two guys? Does the standard forbid an explicit template instantiation declaration to be preceded by an explicit definition? It makes little sense to me. After all, what harm could it be to define first and then declare? Just think about the case with non-template functions.
Upvotes: 1
Views: 813
Reputation: 21000
From [temp.explicit] / 11
If an entity is the subject of both an explicit instantiation declaration and an explicit instantiation definition in the same translation unit, the definition shall follow the declaration.
GCC should be giving an error for the first example too.
Related bug from 2008, GCC seems to have problems detecting the error with classes, the following is also missed
template <typename T> class f {};
template class f<int>;
extern template class f<int>;
int main() {}
Upvotes: 2