以下代码似乎是合理的,但不适用于两个主要的编译器
#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)
c (https://godbolt.org/z/ewBbZJ)
和
msvc (https://godbolt.org/z/6ZmQwj)
不能这样做
此代码符合标准吗?
答案 0 :(得分:4)
GCC错误。 tmp_t
声明一个新模板(精确的别名模板)。而且这个新模板与其他任何模板都不一样。
[临时别名] (强调我的意思)
1模板声明,其中的声明是 alias-declaration声明标识符为别名模板。一个 别名模板是一系列类型的名称。 名称 别名模板是一个模板名称。
粗体文本表示tmp_t
引用了新的别名模板,而不引用任何别名的专业定义。因此S<tmp_t>
和S<Tmp>
是两个带有不同自变量的专业化。
相反,有一些特殊的规则可以使别名模板专业化成为它们所别名的确切内容
2当template-id指代别名的特殊化时 模板,它等效于通过 将其模板参数替换为中的模板参数 别名模板的类型ID。
因此,虽然while模板ID tmp_t<foo>
与Tmp<foo>
的含义完全相同,但tmp_t
本身(不带参数)不是模板ID(它没有命名专业化名称) 。而是将模板命名为另一个实体。
答案 1 :(得分:0)
即使事实证明,在我的情况下,我并不需要它,但有可能规避此缺陷,但前提是模板模板参数的传递仅由开发人员和不是用户。
将模板包装为其他类型...:P
我想马上说:我不认为这是个好主意。使用该代码的代码可能太复杂了,可能是因为它利用了异常的想法。
这个例子确实很糟糕而且牵强。都是因为心态错了。
但是我只想把它放在那里...