std :: initializer_list的实例化的typedef与实例化本身的行为不同。在以下代码(与gcc 4.4.6一起编译)中,使用实例化声明的变量直接需要单括号来进行初始化,而使用typedef声明的变量需要使用双括号。 (奇怪的是,编译器会为前者发出“未使用的变量”警告,但不会为后者发出警告。)此外,显然可以为使用实例化声明的函数参数推导出参数类型,但不能为使用typedef声明的函数参数推导出参数类型。 。
struct S { int a; int b; };
template class std::initializer_list< S >; // same results with or without this
typedef std::initializer_list< S > SL;
void fs1( std::initializer_list< S > data ) {}
void fs2( SL data ) {}
int main()
{
std::initializer_list< S > s11{ { 11, 22 }, { 33, 44 } }; // compiles w/ single parentheses
// std::initializer_list< S > s12{{ { 11, 22 }, { 33, 44 } }}; // ERROR 1
// SL s21{ { 55, 66 }, { 77, 88 } }; // ERROR 2
SL s22{{ { 55, 66 }, { 77, 88 } }}; // compiles w/ double parentheses
fs1( { { 11, 22 }, { 33, 44 } } ); // ok w/ no arg. type
// fs2( { { 55, 66 }, { 77, 88 } } ); // ERROR 3
// fs2( {{ { 55, 66 }, { 77, 88 } }} ); // ERROR 4
// fs2( SL{ { 55, 66 }, { 77, 88 } } ); // ERROR 2
fs2( SL{{ { 55, 66 }, { 77, 88 } }} ); // requires arg. type & double par. to compile
}
// ERROR 1: could not convert '{{{11, 22}, {33, 44}}}' to 'std::initializer_list<S>'
// ERROR 2: no matching function for call to 'std::initializer_list<S>::initializer_list(<brace-enclosed initializer list>)'
// ERROR 3: could not convert '{{55, 66}, {77, 88}}' to 'SL'
// ERROR 4: could not convert '{{{55, 66}, {77, 88}}}' to 'SL'
为什么类型定义实例化的行为与非类型定义实例不同?是否有其他语法可以启用类型推断,而无需为typedef版本指定参数类型?
顺便说一句,我不知道类型别名是否会表现出相同的行为差异,但这不是一个选择,因为我暂时还停留在gcc 4.4.6上。