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>();

铿锵的声音是

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 回答