将别名模板匹配为模板参数
Matching alias template as template argument
考虑以下代码:
#include <type_traits>
template<template<class...> class T, class... U>
struct is_specialization_of : std::false_type{};
template<template<class...> class T, class... U>
struct is_specialization_of<T, T<U...>> : std::true_type{};
template<class T, class U = int>
struct test{};
// (1) ok
static_assert(is_specialization_of<test, test<int>>::value, "1");
template<class T>
using alias = test<T>;
// (2) fails
static_assert(is_specialization_of<alias, alias<int>>::value, "2");
int main()
{
}
为什么(2(,即使用别名模板的static_assert
,失败?
模板参数扣除过程(2(中的扣除过程与(1(中的一个不同?
这是CWG问题1286。问题是:alias
和test
等效吗?曾经在[temp.type]中有一个示例,该示例表明y
和z
在这里具有相同的类型:
template<template<class> class TT> struct X { }; template<class> struct Y { }; template<class T> using Z = Y<T>; X<Y> y; X<Z> z;
该示例被纠正为CWG缺陷1244的一部分 - 正确地表明,[temp.alias]中没有措辞实际上指定别名模板等于它们的模板。那里唯一的措辞是指别名模板专业的等效性:
当A template-id 是指别名模板的专业化时,它等同于通过替换其 template-arguments arguments /em>用于 parameters 在别名模板的 type-id 中。
意图显然是y
和z
do 在此示例中具有相同的类型,这意味着Z
和Y
实际上是等效的。但是,除非并且直到采用决议中的措辞,否则不是。今天,alias
和test
是不是等效的,但是alias<int>
和test<int>
是。这意味着is_specialization_of<alias, alias<int>>
是is_specialization_of<alias, test<int>>
,其中alias
在test
中是唯一的,它与您的部分专业化不匹配,因此是false_type
。
test
和alias
在中仍然不是等效,因为test
采用两个模板参数,并且别名采用一个模板参数。分辨率措辞中的示例模仿了您的示例,并在此处阐明了目的:
template<typename T, U = T> struct A; // ... template<typename V> using D = A<V>; // not equivalent to A: // different number of parameters
我认为没有模板参数列表的别名模板的名称不等于相关类型的名称。因为标准仅指定了一种情况:
14.5.7别名模板[temp.alias]
- 当模板-ID指的专业化模板时,它等效于相关类型 通过替换其模板 - arguments将模板参数替换为Alias的类型ID 模板。[注意:别名模板名称永远不会推导。—端注]
这很好:
static_assert(is_specialization_of<test, alias<int>>::value, "2");
相关文章:
- 部分定义/别名模板模板参数
- 告诉c++编译器该参数没有别名
- 为什么我们不能重复使用具有不同模板参数的别名模板标识符?
- C++模板/别名 - 模板参数列表中参数 1 处的类型/值不匹配
- 模板模板参数和模板别名:编译器错误?
- 为模板参数包添加别名
- C++使用默认模板参数键入别名和转发声明
- 缺少别名模板C++参数列表
- 使用外部定义的模板类型作为模板参数的更通用模板的模板别名
- 必须非常量别名参数及其默认参数常量
- 作为模板参数 c++ 给出的类的别名模板
- 使用其他模板类型参数作为要在函数签名中使用的类型别名声明
- 参数化类的别名(或类型定义)内部类
- C++别名的模板参数包扩展
- 如何简化模板模板参数中的enable_if别名
- 包含可变参数包的第一个可转换类型的别名的结构
- C++ 11 个模板,参数包的别名
- 为什么模板引用类型不能用作模板类型别名参数?
- 具有模板类默认参数的 C++17 别名模板
- 如何用可变数量的参数别名一个函数