简体   繁体   English

可变参数模板的部分特化

[英]Partial specialization of variadic templates

Consider the following class template 'X' and its partial specializations. 考虑以下类模板“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 ?

I suspect X<int> is ambiguous. 我怀疑X <int>是不明确的。 It is because: 这是因为:

It is obvious that both #2 and #3 are more specialized than #1, #2 and #3 are now compared. 很明显,#2和#3都比#1更专业,现在比较#2和#3。 According to 14.5.5.2, let's consider which of the following #2' and #3' is more specialized. 根据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'

According to 14.8.2.4, the first step is the template argument deduction using #2' as the argument template and #3' as the parameter template. 根据14.8.2.4,第一步是模板参数推导,使用#2'作为参数模板,#3'作为参数模板。 Given the only argument type is X<A1>, the deduced T1 is A1, and Types is empty. 给定唯一的参数类型是X <A1>,推导出的T1是A1,而Types是空的。

A = X<A1>, P = X<T1, Types...>  =>  T1 = A1, Types = {}

The second step is done using #3' as the argument template and #2' as the parameter template. 第二步是使用#3'作为参数模板,使用#2'作为参数模板。 Given the only argument type is X<A1, Args...>, according to 14.8.2.5/9 (note that this paragraph is recently revised by N3281), Args is simply ignored, the deduced T1 is A1 and argument deduction succeeds. 鉴于唯一的参数类型是X <A1,Args ...>,根据14.8.2.5/9(注意该段最近由N3281修订),Args被简单地忽略,推断的T1是A1并且参数推断成功。

A = X<A1, Args...>, P = X<T1>  =>  T1 = A1 (Args is ignored)

Finally, the bidirectional argument deductions succeeded. 最后,双向参数推断成功。 So #2 is just as specialized as #3. 所以#2和#3一样专业。 In conclusion, X<int> is ambiguous. 总之,X <int>是模糊的。

My question is: "is my interpretation correct?" 我的问题是:“我的解释是否正确?”

If this interpretation is correct, the definition of 'std::common_type' in 20.9.7.6/3 is inappropriate. 如果这种解释是正确的,那么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;
};

When common_type<A, B> is used, #3 and #4 are ambiguous. 当使用common_type <A,B>时,#3和#4是不明确的。

Note: on the first example, GCC 4.7.0 (snapshot) and Clang 3.0 select #2. 注意:在第一个例子中,GCC 4.7.0(快照)和Clang 3.0选择#2。 However, these compilers are so unreliable that they don't follow the other changes by N3281. 但是,这些编译器非常不可靠,以至于它们不遵循N3281的其他更改。

14.8.2.4, section 11 (I refer to draft N3242). 14.8.2.4,第11节(我参考N3242草案)。

In most cases, all template parameters must have values in order for deduction to succeed, but for partial ordering purposes a template parameter may remain without a value provided it is not used in the types being used for partial ordering. 在大多数情况下,所有模板参数必须具有值以便推断成功,但是对于部分排序目的,模板参数可以保持不带值,前提是它不用于用于部分排序的类型。 [ Note: A template parameter used in a non-deduced context is considered used. [注意:使用非推断上下文中使用的模板参数。 —end note ] [ Example: - 尾注] [示例:

 template <class T> T f(int); // #1 template <class T, class U> T f(U); // #2 void g() { f<int>(1); // calls #1 } 

In your case, #3 will be used. 在您的情况下,将使用#3。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM