当显式模板实例化定义在显式声明之前时,GCC和clang不同意
When explicit template instantiation definition precedes explicit declaration, GCC and clang disagree
查看以下代码:
#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.
这两个家伙怎么了?标准是否禁止显式模板实例化声明之前有显式定义?这对我来说没什么意义。毕竟,先定义再声明又有什么害处呢?
From [temp.explicit]/11
如果一个实体是同一翻译单元中显式实例化声明和显式实例化定义的主题,则定义应遵循声明。
对于第一个例子,GCC也应该给出一个错误。
2008年的相关bug, GCC似乎在检测类的错误时出现了问题,以下内容也被遗漏了
template <typename T> class f {};
template class f<int>;
extern template class f<int>;
int main() {}
相关文章:
- 奇怪的结构&GCC&clang(void*返回类型)
- 如何让 GCC/Clang 在保留标识符上出错
- Visual C++: MSVC vs. GCC+CLANG: 处理 lambda 捕获类成员变量,正确的方法是什么?
- GCC/CLang不同意模板模板参数的部分特化
- 在 gcc/clang (C++) 中获取函数范围之外的标签地址
- C++指向成员的指针的类内初始化会使 MSVC 失败(但 GCC/Clang 工作)
- ICC 中的 -O2 搞砸了汇编程序,ICC 中的 -O1 和 GCC / Clang 中的所有优化都很好
- 为什么GCC/Clang甚至在最高优化水平上也不会内联
- 在继承多个空类时,了解GCC/Clang vs MSVC2015之间的不同填充规则
- C++ MSVC/GCC/Clang编译器错误
- 这被认为是有效的C 11还是C 14?还是GCC/Clang弄错了
- GCC/Clang上的模板错误,但在MSVC上没有错误
- 如何求解与GCC/Clang不同的C 功能模板的MSVC处理(无法识别的模板定义)
- 忽略 gcc/clang 的"-Wmissing-braces"警告是否明智?
- GCC/Clang 返回元组时x86_64 C++ ABI 不匹配?
- 为什么根据 C++11 标准,std::seed_seq是不可复制的,为什么 gcc/clang 不符合?
- 我可以用更新的 gcc/clang 定位较旧的 Linux 吗?C++
- gcc/clang:错误:未知类名"异常";你是说'std::exception'
- 模板专业化和DLL:Visual Studio vs. (GCC / Clang)
- 使用GCC/CLANG跟踪代码膨胀的工具