1

次のコードを参照してください。

#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.

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

4

1 に答える 1

2

[temp.explicit] / 11 から

エンティティが同じ翻訳単位内の明示的なインスタンス化宣言と明示的なインスタンス化定義の両方の対象である場合、定義は宣言に従うものとします。

GCC は最初の例でもエラーを出すはずです。

2008年からの関連バグ、GCCはクラスでエラーを検出するのに問題があるようです、以下も見逃されています

template <typename T> class f {};

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

int main() {}
于 2015-10-02T05:15:43.937 に答える