请参阅以下代码:
#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的消息是
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.
与这两个家伙有什么关系?标准是否禁止显式模板实例化声明前面有明确的定义?这对我来说没什么意义。毕竟,首先定义然后声明会有什么害处?试想一下非模板函数的情况。
答案 0 :(得分:2)
来自[temp.explicit] / 11
如果实体是同一翻译单元中的显式实例化声明和显式实例化定义的主题,则该定义应遵循声明。
GCC也应该为第一个例子提供错误。
2008年的相关bug,GCC似乎在检测类错误时遇到问题,以下内容也错过了
template <typename T> class f {};
template class f<int>;
extern template class f<int>;
int main() {}