C ++ 11
Программа инициализирует vector
по имени myVec
из int
vector
s, а затем использует цикл для распечатки каждого внутреннего 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]
компилирует, почему не остальное?
Попробуйте скомпилировать этот код. это должно объяснить вашу проблему:
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)
Других решений пока нет …