typedef создания экземпляра std :: initializer_list - PullRequest
0 голосов
/ 14 декабря 2018

Определение типа экземпляра std :: initializer_list не ведет себя так же, как само создание.В следующем коде (скомпилированном с 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.

...