Равномерная инициализация на вектор векторов целых чисел

C ++ 11

Программа инициализирует vectorпо имени myVecиз int vectors, а затем использует цикл для распечатки каждого внутреннего vectorэлементы. Но я получил неожиданные результаты, пытаясь увидеть, что происходит, когда я использую дополнительные фигурные скобки. Следующее также на это LiveWorkSpace для легкого переключения между компиляторами. g++ 4.8.0 компилируется только до myVec[5], clang++ 3.2 компилирует все:

#include <iostream>
#include <vector>

int main()
{
std::vector<std::vector<int>> myVec =
{
/* myVec[0] */ {1, 2},
/* myVec[1] */ {},
/* myVec[2] */ {{}},
/* myVec[3] */ { {}, {} },
/* myVec[4] */ { {}, {}, {} },
/* myVec[5] */ {{{}}}

/* myVec[6] */  // , { {{}}, {{}} }       // g++ 4.8.0 COMPILER ERROR
/* myVec[7] */  // , {{{{}}}}             // g++ 4.8.0 COMPILER ERROR
/* myVec[8] */  // , { {{{}}}, {{{}}} }   // g++ 4.8.0 COMPILER ERROR
};

// loop for printing
for (unsigned int i = 0; i < myVec.size(); ++i)
{
std::cout << "myVec[" << i << "]: ";
for (unsigned int j = 0; j < myVec.at(i).size(); ++j)
{
std::cout << myVec.at(i).at(j) << ", ";
}
std::cout << std::endl;
}
return 0;
}

фактический g++ 4.8.0 выход:

myVec[0]: 1, 2,
myVec[1]:
myVec[2]: 0,
myVec[3]: 0, 0,
myVec[4]: 0, 0, 0,
myVec[5]: 0,

Анализ:

myVec[0] : {1, 2} :

Получил ожидаемый выход.

myVec[1] : {} :

Получил ожидаемый выход.

myVec[2] : {{}} :

Это вектор int 0, Внутренняя скобка инициализирует int в 0,

myVec[3] : { {}, {} } :

Две внутренние скобки инициализируют int каждый для 0,

myVec[4] : { {}, {}, {} } :

Три внутренних скобки инициализируют int каждый для 0,

myVec[5] : {{{}}} :

Я хотел добавить еще один набор фигурных скобок для myVec[2] чтобы увидеть, как далеко я могу пойти с добавлением фигурных скобок, прежде чем получить ошибки компилятора. Я не понимаю, почему это компилируется и почему его элемент печатается как 0,

Например, int j = {} инициализирует j в 0, vector<vector<int>> v = { {{}} } инициализирует самое внутреннее {} в int 0что делает его эквивалентным vector<vector<int>> v = { {0} }, Тогда что vector<vector<int>> u = { {{{}}} } и с чего бы это компилировать?

Гипотетический myVec[6] : { {{}}, {{}} } :

Следуя той же схеме, что и выше, я хотел создать вектор, содержащий два набора двойных фигурных скобок. Но это не компилируется, и я не понимаю, почему это нарушает схему предоставления мне нескольких нулей.

Гипотетический myVec[7] : {{{{}}}} :

Я хотел добавить еще один набор фигурных скобок для myVec[5] чтобы увидеть, как далеко я могу пойти с добавлением фигурных скобок, прежде чем получить ошибки компилятора. Я не понимаю, почему это нарушает шаблон и не компилируется.

Гипотетический myVec[8] : { {{{}}}, {{{}}} } :

Я хотел продлить myVec[7] чтобы сделать вектор с двумя наборами тройных скобок. Я не понимаю, почему это не компилируется либо.

Если все до myVec[5] компилирует, почему не остальное?

11

Решение

Попробуйте скомпилировать этот код. это должно объяснить вашу проблему:

int i = {};   // initializes i to int()
int j = {{}}; // fails to compile

Зачем {{{}}} принимается в вашем коде, похоже, ошибка gcc (необходимо уточнить), связанная с обработкой ctor:

struct foo {
foo( std::initializer_list<int> ) {}
};
void f()
{
foo bar1( {{{}}} ); // compiles fine
foo bar2 = {{{}}}; // compiles fine
}

Редактировать (спасибо Йоханнесу Шаубу) — удаление копии ctor делает первый вариант не компилируемым:

struct foo {
foo( std::initializer_list<int> ) {}
foo( const foo& ) = delete;
};
void f()
{
foo bar1( {{{}}} ); // fails to compile: use of deleted function ‘foo::foo(const foo&)’
foo bar2 = {{{}}}; // still compiles, neither deleting move ctor, nor assignment operator does not affect that, is copy ctor of std::initializer_list involved?
}

для функции-члена не получается:

struct foo {
void moo( std::initializer_list<int> ) {}
};
void f()
{
foo bar;
bar.moo( {{{}}} ); // fails to compile
}

Этот код также не работает:

std::initailizer_list<int> l = {{{}}}; // fails to compile

Та же самая ситуация ctor против функции-члена для std :: vector:

void f()
{
std::vector<int> v( {{{}}} ) // compiles fine;
v.assign( {{{}}} ); // fails to compile
};

gcc версия 4.7.2 (Ubuntu / Linaro 4.7.2-2ubuntu1)

4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]