繁体   English   中英

可变参数模板的部分特化

[英]Partial specialization of variadic templates

考虑以下类模板“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 <int>是不明确的。 这是因为:

很明显,#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 <A1>,推导出的T1是A1,而Types是空的。

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

第二步是使用#3'作为参数模板,使用#2'作为参数模板。 鉴于唯一的参数类型是X <A1,Args ...>,根据14.8.2.5/9(注意该段最近由N3281修订),Args被简单地忽略,推断的T1是A1并且参数推断成功。

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

最后,双向参数推断成功。 所以#2和#3一样专业。 总之,X <int>是模糊的。

我的问题是:“我的解释是否正确?”

如果这种解释是正确的,那么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 <A,B>时,#3和#4是不明确的。

注意:在第一个例子中,GCC 4.7.0(快照)和Clang 3.0选择#2。 但是,这些编译器非常不可靠,以至于它们不遵循N3281的其他更改。

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。

暂无
暂无

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

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