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

时间:2017-04-25 19:13:03

标签: c++ c++11 templates language-lawyer

考虑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)中的模板参数推导过程有何不同?

2 个答案:

答案 0 :(得分:13)

这是CWG issue 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 defect 1244的一部分进行了更正 - 这正确表明[temp.alias]中没有任何措辞实际上指定别名模板与其别名的模板等效。那里唯一的措辞是指别名模板特化的等价:

  

template-id 引用别名模板特化时,它等同于通过替换其 template-arguments <获得的关联类型/ em>用于别名模板的 type-id 中的 template-parameters

显然,yz 的意图在此示例中具有相同的类型,这意味着ZY实际上是alias当量。但除非并且直到决议的措辞获得通过,否则它们不会。今天,testalias<int> 等效,但test<int>is_specialization_of<alias, alias<int>> 。这意味着is_specialization_of<alias, test<int>>alias,其中testfalse_type中是唯一的,与您的部分专业化不匹配,因此为test

此外,即使采用#1286中的措辞,aliastest 仍然不等同,因为template<typename T, U = T> struct A; // ... template<typename V> using D = A<V>; // not equivalent to A: // different number of parameters 需要两个模板参数和别名需要一个模板参数。解决方案措辞中的示例模仿了您的示例并阐明了其意图:

<%
Set objConn = Server.CreateObject("ADODB.Connection")
objConn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="&Server.MapPath("miodb.mdb")
Set objRs = Server.CreateObject("ADODB.Recordset")
strSQL="SELECT * FROM articoli"
objRs.Open strSQL, objConn,3,3

For each field in objRs.Fields
%>

<div class="form-group">
    <div class="input-group">
      <div class="input-group-addon"><b><%=field.name%></b></div>
      <input type="<%=field.name%>" class="form-control" id="exampleInputAmount" name="<%=field.name%>">
      <div class="input-group-addon">mq</div>
    </div>
</div>


<% Next %>

答案 1 :(得分:2)

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

  

14.5.7别名模板[temp.alias]

     
      
  1. 当template-id引用别名模板的特化时,它等同于关联的类型   通过将其模板参数替换为别名的type-id中的模板参数来获得   模板。 [注意:永远不会推断出别名模板名称。-end note]
  2.   

works fine

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