通过using别名显式特化类模板是否符合C++标准?
问题
我试了一段代码,在GCC、Clang、MSVC、icc等编译器上都能正常运行,想确认这是偶然现象还是C++标准允许的写法?
从逻辑上看这像是现有特性的合理延伸,但这个语法看起来有点奇怪,我担心自己是不是在依赖非标准实现:
#include <type_traits> template <int, bool> void Bar(); template <int i> struct A { struct T : std::true_type {}; static void Foo() { Bar<i, T::value>(); } }; // 常规写法: template <> struct A<1>::T : std::false_type {}; // 这种写法看起来很奇怪,但也能运行: using A3 = A<3>; template <> struct A3::T : std::false_type {}; void Go() { A<0>::Foo(); // 调用 Bar<0, true>() A<1>::Foo(); // 调用 Bar<1, false>() A<2>::Foo(); // 调用 Bar<2, true>() A<3>::Foo(); // 调用 Bar<3, false>() }
回答
这完全符合C++标准,不是编译器的非标准扩展。
核心原因在于:using A3 = A<3>; 定义的是类型别名,A3和A<3>是同一个类型,没有任何区别。当你写template <> struct A3::T时,本质上就是在特化A<3>::T,和直接写template <> struct A<3>::T完全等价。
C++标准允许通过类型别名指代模板实例,进而对其嵌套类型进行特化,只要别名对应的是明确的模板实例化类型即可。你看到的编译器一致支持,正是因为它们都遵循了标准的这一规定,绝非偶然现象。
需要注意的是:如果别名指代的不是明确的模板实例(比如别名本身是未实例化的模板别名),这种特化写法就不合法,但你的例子里A3是明确的A<3>实例,所以完全没问题。
内容的提问来源于stack exchange,提问作者BCS
相关产品推荐
相关产品推荐

