Инициализировать несколько переменных, разделенных запятой ','

Используя С++ 14, если я хочу объявить и инициализировать два целых числа в одной инструкции (используя разделитель-запятую):

int i,j = 0;
std::cout << i << "," << j << std::endl;

Тогда правильно инициализируется только самая правая переменная (j). Действительно, компилятор выводит предупреждающее сообщение:

предупреждение: 'i' используется неинициализированным в этой функции [-Wuninitialized]

Конечно, решение состоит в том, чтобы повторить это для каждой переменной.

int i=0, j=0;

Но вопрос в следующем:

Есть ли способ правильно инициализировать несколько переменных только одним оператором присваивания?


person Pierre Nicolas    schedule 08.01.2018    source источник
comment
Нет, нет.   -  person Some programmer dude    schedule 08.01.2018
comment
Как показывает Калет, в C++17 есть. До этого вы можете, по крайней мере, избежать повторения правой стороны, используя int i = j = 0 и т. д., но я действительно не хочу поощрять это...   -  person underscore_d    schedule 08.01.2018
comment
Знак равенства в int i=0; не является присваиванием... это объявление со значением инициализатора. Как вы различаете случай int i, j = 0;, когда вы не хотите, чтобы i инициализировалось, а две переменные были инициализированы одним и тем же значением? Что тогда должно означать int i = 0, j;?   -  person Luis Colorado    schedule 09.01.2018
comment
Чтобы различать их, вы можете написать их в двух разных инструкциях. Но на самом деле мой вопрос был больше: если я хочу создать 26 переменных подряд и мне лень их инициализировать одну за другой (int a=0, b=0, ..., z=0), нужно ли мне есть обходной путь?   -  person Pierre Nicolas    schedule 11.01.2018


Ответы (3)


К сожалению, нет; это причуда грамматики.

int i(0), j(0);

альтернатива, действующая с C++98. Если вам не нравится повторять литерал 0, вы можете, по крайней мере, для этого особого случая, писать с С++ 11 и далее

int i{}, j{};
person Bathsheba    schedule 08.01.2018
comment
А с C++ 11 вы также можете использовать int i{ 0 }, j{ 0 }; - person Carl; 08.01.2018
comment
с/к сожалению/радостно. Не поощряйте несколько объявлений, иначе вы получите int * i, j = nullptr; и т. д. - person Caleth; 08.01.2018
comment
@Carl: даже лучше, ты можешь отбросить нули. - person Bathsheba; 08.01.2018
comment
Ага! Но плохо то, что я повторяю '{}' вместо '=0' ;-) - person Pierre Nicolas; 11.01.2018
comment
@GenghisCat: Да, но на самом деле вы не повторяете буквальное значение. По крайней мере, на мой взгляд, это удовлетворяет СУХОЕ программирование. en.wikipedia.org/wiki/Don%27t_repeat_yourself - person Bathsheba; 11.01.2018

В C++17 и более поздних версиях вы можете:

auto [i, j] = std::tuple(0, 0);
person Caleth    schedule 08.01.2018

Вы можете инициализировать несколько переменных одним оператором присваивания, но не при их объявлении:

int i, j;
std::tie(i, j) = std::make_tuple(0, 0);
person piwi    schedule 08.01.2018
comment
А в C++17 и более поздних версиях вы можете auto [i, j] = std::tuple(0, 0); - person Caleth; 08.01.2018
comment
Ну, если это не при объявлении, то это не инициализация, не так ли? Это задание. Переменные остаются неинициализированными между объявлением и присваиванием, что является плохой практикой, риском и невозможно для неприсваиваемых типов. В основном, как сформулировано, это не отвечает на вопрос. - person underscore_d; 08.01.2018
comment
@underscore_d Действительно, это не инициализация, мой плохой. Что касается плохой практики и риска, это спорно и действительно зависит от контекста. - person piwi; 08.01.2018