次のコードを参照してください。
#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.
二人の男に何が起こっているのですか?標準は、明示的なテンプレートのインスタンス化宣言の前に明示的な定義を行うことを禁止していますか? 私にはほとんど意味がありません。結局のところ、最初に定義してから宣言すると、どのような害があるのでしょうか? 非テンプレート関数の場合について考えてみてください。