n. m. could be an AI
n. m. could be an AI

Reputation: 119877

Strange behaviour of default template-argument in a template-template-parameter

Consider this C++11 program:

#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;
}

When compiled with either gcc or clang, the output is 41.

Is this behaviour according to the standard? Where exactly does the standard specify it (for both Wrap1 and Wrap2)?

This question is inspired in part by this other question.

Upvotes: 21

Views: 339

Answers (1)

Jun Ge
Jun Ge

Reputation: 420

In Wrap2 class, parameter pack "class... E" will replace all the parameters specified by "class C" ( include the default "int" parameter), so "Wrap2 w2" will return 1 which is the default parameter of struct Cont.

Parameter pack replaced all the parameters of class C, so the default parameters of C didn't work here.

#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

Upvotes: 1

Related Questions