std :: initializer_list实例化的typedef

时间:2018-12-14 04:20:11

标签: c++ typedef initializer-list

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上。

0 个答案:

没有答案