考虑以下类模板'X'及其部分特化。
template <class ...Types>
struct X {}; // #1
template <class T1>
struct X<T1> {}; // #2
template <class T1, class ...Types>
struct X<T1, Types...> {}; // #3
X<int> x; // #2 or #3 ?
我怀疑X&lt; int&gt;很暧昧。这是因为:
很明显,#2和#3都比#1更专业,#2和#3现在进行了比较。根据14.5.5.2,让我们考虑以下哪个#2'和#3'更专业。
template <class T1>
void f(X<T1>); // #2'
template <class T1, class ...Types>
void f(X<T1, Types...>); // #3'
根据14.8.2.4,第一步是模板参数推导,使用#2'作为参数模板,#3'作为参数模板。给定唯一的参数类型是X&lt; A1&gt;,推导出的T1是A1,而类型是空的。
A = X<A1>, P = X<T1, Types...> => T1 = A1, Types = {}
第二步是使用#3'作为参数模板,#2'作为参数模板。鉴于唯一的参数类型是X&lt; A1,Args ...&gt;,根据14.8.2.5/9(注意该段最近由N3281修订),Args被简单地忽略,推断的T1是A1并且参数推断成功
A = X<A1, Args...>, P = X<T1> => T1 = A1 (Args is ignored)
最后,双向参数推断成功。所以#2和#3一样专业。总之,X&lt; int&gt;很暧昧。
我的问题是:“我的解释是否正确?”
如果这种解释是正确的,那么20.9.7.6/3中'std :: common_type'的定义是不合适的。
template <class ...T>
struct common_type; // #1
template <class T>
struct common_type<T> // #2
{
typedef T type;
};
template <class T, class U>
struct common_type<T, U> // #3
{
typedef
decltype(true ? declval<T>() : declval<U>())
type;
};
template <class T, class U, class ...V>
struct common_type<T, U, V...> // #4
{
typedef typename
common_type<typename common_type<T, U>::type, V...>::type
type;
};
当common_type&lt; A,B&gt;使用时,#3和#4是不明确的。
注意:在第一个例子中,GCC 4.7.0(快照)和Clang 3.0选择#2。但是,这些编译器是如此不可靠,以至于它们不遵循N3281的其他更改。
答案 0 :(得分:8)
14.8.2.4,第11节(我参考N3242草案)。
在大多数情况下,所有模板参数都必须具有值 扣除成功,但为了部分订购目的的模板 参数可以保持没有值,只要它没有被使用 用于部分排序的类型。 [注意:模板参数 在非推断的上下文中使用的被认为是使用的。 - 尾注] [ 示例:
template <class T> T f(int); // #1 template <class T, class U> T f(U); // #2 void g() { f<int>(1); // calls #1 }
在您的情况下,将使用#3。