问题描述
考虑以下代码:
#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
)失败?
Why does (2), i.e. static_assert
that uses alias template, fail?
(2)中的模板参数推导过程与(1)中的模板推论过程有何不同?
How does the template argument deduction process in (2) differ from the one in (1)?
推荐答案
这是 CWG问题1286 .问题是:alias
和test
是否等效? [temp.type]中曾经有一个示例,建议y
和z
在此处具有相同的类型:
This is CWG issue 1286. The question is: are alias
and test
equivalent? There used to be an example in [temp.type] which suggested that y
and z
have the same type here:
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 的一部分得到纠正. a>-正确表示 [temp.alias] 中没有措辞实际上指定别名模板与其别名模板等效.那里唯一的措辞是指别名模板专业化的等效性:
The example was corrected as part of CWG defect 1244 - which indicated correctly that there is no wording in [temp.alias] that actually specifies that alias templates are equivalent to the templates they alias. The only wording there refers to equivalence of alias template specializations:
在此示例中,意图显然是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
.
The intent is apparently that y
and z
do have the same type in this example, meaning that Z
and Y
are actually equivalent. But unless and until the wording in the resolution is adopted, they are not. Today, alias
and test
are not equivalent but alias<int>
and test<int>
are. This means that is_specialization_of<alias, alias<int>>
is is_specialization_of<alias, test<int>>
, where alias
is unique from test
, which would not match your partial specialization and thus be false_type
.
此外,即使采用#1286中的措词,test
和alias
仍然不等价 ,原因很明显,原因是test
采用两个模板参数,而别名采用一个模板参数.解决方案措辞中的示例模仿了您的示例,并在此处阐明了意图:
Moreover, even with the adoption of the wording in #1286, test
and alias
are still not equivalent for the obvious reason that test
takes two template parameters and alias takes one template parameter. The example in the resolution wording mimics your example and clarifies the intent here:
template<typename T, U = T> struct A;
// ...
template<typename V>
using D = A<V>; // not equivalent to A:
// different number of parameters
这篇关于匹配别名模板作为模板参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!