GCC与Clang/MSVC类内显式特化成员函数模板编译合规性问题
结论
GCC的编译行为完全符合C++标准要求,Clang、MSVC此处属于实现了非标准的编译器扩展。
标准依据
C++标准明确规定:模板的显式特化声明必须定义在对应模板所属的命名空间作用域下,不允许直接在类、结构体的内部非命名空间作用域,声明其成员函数模板的显式特化。
示例代码中直接在struct C的类作用域内编写template<> void f<int>()的显式特化,本身就不符合标准语法,这和GCC给出的explicit specialization in non-namespace scope 'struct C'错误提示完全对应。
Clang、MSVC默认放行这种写法属于厂商自定义的兼容扩展,不属于标准C++规定的合法语法。如果开启严格标准合规模式(Clang添加-pedantic-errors编译参数、MSVC添加/permissive-编译参数),这两个编译器同样会对这段代码抛出语法错误。
标准合规写法
如果要写出所有编译器都能在标准模式下正常编译的代码,需要把成员函数模板的显式特化移到类外的命名空间作用域,示例如下:
struct C { template<typename T> void f() { } }; // 显式特化放在类外的命名空间作用域,符合C++标准要求 template<> void C::f<int>() { } int main() { return 0; }
内容的提问来源于stack exchange,提问作者Anoop Rana
相关产品推荐
相关产品推荐

