#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)中的模板参数推导过程有何不同?
答案 0 :(得分:13)
这是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]中没有任何措辞实际上指定别名模板与其别名的模板等效。那里唯一的措辞是指别名模板特化的等价:
当 template-id 引用别名模板的特化时,它等同于通过替换其 template-arguments <获得的关联类型/ em>用于别名模板的 type-id 中的 template-parameters 。
显然,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
中是唯一的,与您的部分专业化不匹配,因此为test
。
此外,即使采用#1286中的措辞,alias
和test
仍然不等同,因为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]
- 当template-id引用别名模板的特化时,它等同于关联的类型 通过将其模板参数替换为别名的type-id中的模板参数来获得 模板。 [注意:永远不会推断出别名模板名称。-end note]
醇>
static_assert(is_specialization_of<test, alias<int>>::value, "2");