Consider this C++11 program:
考虑一下这个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;
}
When compiled with either gcc or clang, the output is 41
.
使用gcc或clang编译时,输出为41。
Is this behaviour according to the standard? Where exactly does the standard specify it (for both Wrap1
and Wrap2
)?
这种行为是否符合标准?标准究竟在哪里指定它(对于Wrap1和Wrap2)?
This question is inspired in part by this other question.
这个问题部分受到另一个问题的启发。
1 个解决方案
#1
1
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.
在Wrap2类中,参数包“class ... E”将替换“class C”指定的所有参数(包括默认的“int”参数),因此“Wrap2 w2”将返回1,这是struct Cont的默认参数。
Parameter pack replaced all the parameters of class C, so the default parameters of C didn't work here.
参数包替换了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
#1
1
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.
在Wrap2类中,参数包“class ... E”将替换“class C”指定的所有参数(包括默认的“int”参数),因此“Wrap2 w2”将返回1,这是struct Cont的默认参数。
Parameter pack replaced all the parameters of class C, so the default parameters of C didn't work here.
参数包替换了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