考虑 following code :
#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 issue 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 defect 1244 的一部分进行了更正- 正确地表明 [temp.alias] 中没有措辞实际上指定别名模板等同于它们别名的模板。那里唯一的措辞是指别名模板特化的等价性:
When a template-id refers to the specialization of an alias template, it is equivalent to the associated type obtained by substitution of its template-arguments for the template-parameters in the type-id of the alias template.
意图显然是 y
和 z
确实在此示例中具有相同的类型,这意味着 Z
和 Y
实际上是等价的。但除非并且直到决议中的措辞获得通过,否则它们不会。今天,alias
和 test
不等价于alias<int>
和 test<int>
是。这意味着 is_specialization_of<alias, alias<int>>
是is_specialization_of<alias, test<int>>
, 其中alias
是独一无二的 test
,这与您的部分特化不匹配,因此是 false_type
.
此外,即使采用#1286 中的措辞,test
和 alias
仍然不等价,原因很明显 test
接受两个模板参数,alias 接受一个模板参数。决议措辞中的示例模仿了您的示例并阐明了此处的意图:
template<typename T, U = T> struct A; // ... template<typename V> using D = A<V>; // not equivalent to A: // different number of parameters
关于c++ - 匹配别名模板作为模板参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44621204/