问题描述
以下代码似乎是合理的,但不适用于两个主要的编译器
The following code seems reasonable, but doesn't work on two major compilers
#include <type_traits>
template<template<class> class Tmp>
struct S{
template<class T>
using tmp_t = Tmp<T>;
static_assert(std::is_same_v< S<tmp_t>, S<Tmp> >,
"Not same?? How come?");
};
template<class> struct Dummy{};
template struct S<Dummy>;
以 7.1 开头的
gcc 可以正常编译( https://godbolt.org/z/DjAcgP )
gcc starting with 7.1 compiles alright ( https://godbolt.org/z/DjAcgP )
c语( https://godbolt.org/z/ewBbZJ )
和
msvc ( https://godbolt.org/z/6ZmQwj )
不能这样做
clang ( https://godbolt.org/z/ewBbZJ )
and
msvc ( https://godbolt.org/z/6ZmQwj )
fail to do so
此代码符合标准吗?
推荐答案
GCC错误. tmp_t
声明一个新模板(精确的别名模板).而且这个新模板不同于其他模板.
GCC is wrong. tmp_t
declares a new template (an alias template to be precise). And this new template is distinct from any other template.
1 模板声明,其中的声明是一个 alias-declaration声明标识符为别名模板.一个 别名模板是一系列类型的名称. 名称 别名模板是一个模板名称.
1 A template-declaration in which the declaration is an alias-declaration declares the identifier to be an alias template. An alias template is a name for a family of types. The name of the alias template is a template-name.
粗体字表示tmp_t
引用新的别名模板,而不引用任何别名的专业名称.因此,S<tmp_t>
和S<Tmp>
是两个带有不同自变量的专业化.
The text in bold means that tmp_t
refers to the new alias template, it does not refer to whatever the alias' specializations may be defined as. As such S<tmp_t>
and S<Tmp>
are two specializations with different arguments.
相反,有一些特殊的规则可以使别名模板专业化成为它们所别名的确切内容
To contrast, there are special rules that make alias template specializations stand in for the exact thing they alias
因此,虽然while模板ID tmp_t<foo>
的含义与Tmp<foo>
完全相同,但tmp_t
本身(不带参数)不是模板ID(它没有命名专门名称).而是将模板命名为另一个实体.
So the while template-id tmp_t<foo>
means exactly the same thing as Tmp<foo>
, tmp_t
itself (without arguments) is not a template-id (it does not name a specialization). Instead it names the template, a different entity.
这篇关于模板的别名.谁是对的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!