模板模板参数中默认模板参数的奇怪行为

时间:2016-11-30 22:49:26

标签: c++ c++11 variadic-templates template-templates

考虑这个C ++ 11程序:

#include <iostream>

template <class A, class B = char> struct Cont {
    Cont () { std::cout << sizeof(B); }
};

template <template<class, class = int> class C, class E> class Wrap1
{
    C<E> ce;
};

template <template<class, class = int> class C, class... E> class Wrap2
{
    C<E...> ce;
};

int main ()
{
    Wrap1<Cont, void> w1;
    Wrap2<Cont, void> w2;
}

使用gcc或clang编译时,输出为41

这种行为是否符合标准?标准究竟在哪里指定它(对于Wrap1Wrap2)?

这个问题的灵感部分来自this other question

1 个答案:

答案 0 :(得分:1)

在Wrap2类中,参数包“class ... E”将替换“class C”指定的所有参数(包括默认的“int”参数),因此“Wrap2 w2”将返回1,这是默认参数结构续。

参数包替换了C类的所有参数,因此C的默认参数在这里不起作用。

#include <iostream>
#include <typeinfo>

template <class A=char, class B = short, class C = int> struct MyTest
{
    MyTest ()
    {
        std::cout << sizeof(A) << " " << typeid(A).name() << " ";
        std::cout << sizeof(B) << " " << typeid(B).name() << " ";
        std::cout << sizeof(C) << " " << typeid(C).name() << std::endl;
    }
};

template <template<class = double, class = double, class = double> class D, class E, class... F> class Wrap
{
    D<E> de; // the parameters of D is: E + default parameters of D.
    D<F...> df; // the parameters of D is: F... + default parameters of MyTest, the default parameter of D don't work, it will be replaced by pack F.
};

int main ()
{
    Wrap<MyTest, int, int> w;
}

//g++ 5.4.0
//output:
//4 i 8 d 8 d
//4 i 2 s 4 i