提问者:小点点

匹配别名模板作为模板参数


请考虑以下代码:

#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)中的有何不同?


共2个答案

匿名用户

这是CWG第1286期。 问题是:aliastest等价吗? [temp.type]中曾经有一个示例,它建议yz在这里具有相同的类型:

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]中没有实际指定别名模板等同于它们所别名的模板的措辞。 其中唯一的措辞是指别名模板专门化的等价性:

当template-id引用别名模板的专门化时,它等效于通过将其template-参数替换为别名模板type-id中的template-parameters而获得的关联类型。

其意图显然是yz在本例中具有相同的类型,这意味着zy实际上是等价的。 但是,除非和直到决议中的措辞获得通过,否则它们不是。 今天,别名测试并不等价,但别名test是等价的。 这意味着is_specialization_ofis_specialization_of,其中aliastest是唯一的,这将不匹配您的部分专门化,因此是false_type

此外,即使采用#1286中的措辞,testalias仍然不等价,原因很明显,test采用两个模板参数,alias采用一个模板参数。 决议措辞中的示例模仿了您的示例,并阐明了此处的意图:

template<typename T, U = T> struct A;

// ...

template<typename V>   
  using D = A<V>;      // not equivalent to A:
                       // different number of parameters

匿名用户

我认为没有模板参数列表的别名模板的名称不等同于关联类型的名称。 因为standard只指定了一种情况:

14.5.7别名模板[temp.Alias]

这很好用:

static_assert(is_specialization_of<test, alias<int>>::value, "2");