Такой код компилируется:
#include <vector>
int main(int argc, char* argv[])
{
std::vector<int> v2 = { { {} } };
std::vector<int> v3 { { {} } };
std::vector<int> v4 { { { 1 } } };
std::vector<int> v5 ({ { { 1 } } });
return 0;
}
Почему? Как интерпретируются множественные фигурные скобки? Если бы была одна пара скобок, это был бы initializer_list. А во что преобразуются три пары скобок? И почему именно три, а не больше (в GCC)? (Visual Studio 2013 допускает в этой ситуации произвольное количество скобок.)
Все варианты используют конструктор std::vector<int>
, инициализирующий его из std::intializer_list<int>
, а четвертый вариант затем еще использует конструктор копирования вектора.
В данном случае наличие или отсутствие =
в синтаксисе лист-инициализации в первых трех вариантах роли не играет, т.е. никакой разницы в семантике первых двух вариантов нет.
Вариант
std::vector<int> v2 = { { {} } };
аналогичен
std::intializer_list<int> temp_list = { {} };
std::vector<int> v2 = { temp_list };
При этом {}
является корректным инициализатором для объекта типа int
, т.е.
std::intializer_list<int> temp_list = { {} };
в свою очередь аналогично просто
int temp_int = {}; // инициализация нулем
std::intializer_list<int> temp_list = { temp_int };
Вариант
std::vector<int> v3 { { {} } };
это, как уже говорилось выше, то же самое, только в синтаксисе прямой лист-инициализации.
В варианте
std::vector<int> v4 { { { 1 } } };
{ 1 }
- вполне корректный инициализатор для объекта типа int
. Т.е. этот вариант аналогичен
int temp_int = { 1 };
std::intializer_list<int> temp_list = { temp_int };
std::vector<int> v4 = { temp_list };
А вот вариант
std::vector<int> v5 ({ { { 1 } } });
использует уже конструктор копирования класса std::vector<int>
, т.е. аналогичен
std::vector<int> temp_vector = { { { 1 } } }; // см. вариант 3
std::vector<int> v5(temp_vector);
Например, если мы объявим искусственный класс
struct S
{
S(std::initializer_list<int> l) {}
S(const S&) = delete;
};
то первые три варианта прекрасно скомпилируются и для него, а вот четвертый - откажется компилироваться по причине удаленного конструктора копирования.
Попытки увеличивать количество скобок приводят к формированию неправильного инициализатора на самом нижнем уровне: ни { {} }
, ни { { 1 } }
уже не являются корректными инициализаторами для объекта типа int
. Поэтому код не компилируется. Кстати, у меня и VS2015 отказывается компилировать варианты с увеличенным количеством скобок.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Ищу наличие подстроки в строке, но не знаю, как сделать это правильноНапример, мне нужна позиция substring в string
как работать с подключенным по USB Андроид устройством? К примеру, как не используя adb установить apk в устройство, либо запуллить туда что-то?...