Подтвердить что ты не робот

Странное поведение шаблона-аргумента по умолчанию в шаблоне-шаблоне-параметре

Рассмотрим эту программу С++ 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.

Это поведение соответствует стандарту? Где именно стандарт указывает его (для Wrap1 и Wrap2)?

Этот вопрос частично вдохновлен другим вопросом.

4b9b3361

Ответ 1

В классе Wrap2 пакет параметров "class... E" заменит все параметры, указанные в "классе C" (включите параметр "int" по умолчанию), поэтому "Wrap2 w2" вернет 1, который является параметром по умолчанию структуры Cont.

Пакет параметров заменил все параметры класса 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