别名模板与原始模板是否属于同一模板模板参数?
C++模板别名与原始模板的模板模板参数匹配问题
我编写了一段C代码,通过模板别名将myTuple定义为std::tuple的别名,随后自定义is_same模板用于判断两个模板模板参数是否相同。在使用static_assert验证myTuple与std::tuple是否相同时,Clang、MSVC编译报错,而GCC编译通过。请问哪种编译器行为符合C标准?为何别名模板在此场景下与原始模板表现不同?
测试代码
#include <tuple> #include <type_traits> template <class... Ts> using myTuple = std::tuple<Ts...>; template <template <class...> class Lhs, template <class...> class Rhs> struct is_same : public std::false_type {}; template <template <class...> class T> struct is_same<T, T> : public std::true_type {}; int main() { static_assert(is_same<myTuple, std::tuple>::value, "not same"); }
各编译器编译结果
Clang
<source>:18:5: error: static_assert failed due to requirement 'is_same<myTuple, std::tuple>::value' "not same" static_assert(is_same<myTuple, std::tuple>::value, "not same"); ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
MSVC
<source>(18): error C2338: static_assert failed: 'not same'
GCC
(no errors)
解答
符合标准的编译器行为:Clang和MSVC的行为是符合C++标准的,GCC的处理属于非标准扩展。
原因分析:
- C++标准中,模板别名(
template alias)是一个独立的模板实体,它和被别名的原始模板并不等价,即使二者的实例化结果完全相同。 - 当模板别名被作为模板模板参数传递时,它会被视为一个与原始模板完全不同的模板参数。你的
is_same模板特化仅在两个模板模板参数是同一个模板实体时才会匹配true_type,而myTuple和std::tuple是两个独立的模板实体,因此会匹配主模板的false_type,最终导致static_assert失败。 - GCC在此处做了特殊处理,将模板别名与原始模板视为等价的模板模板参数,但这并不符合C++标准的明确规定。
- C++标准中,模板别名(
内容的提问来源于stack exchange,提问作者DNKpp
相关产品推荐
相关产品推荐

