Ответ 1
В
int a = 5, b = 6;
for (auto & i : {a, b})
У вас есть {a, b}
- это std::initialiser_list
двух элементов, a
и b
, в которых скопированы значения a
и b
. Теперь std::initializer_list
предоставляет постоянные итераторы для своих элементов, потому что initializer_list
неизменяемы, поэтому вы не можете привязать значение к ссылкам const
lvalue.
Один вариант заключается в том, чтобы передать указатели вместо этого, что сделало бы указатели самими постоянными, но не значение, на которое они указывают:
for (auto& i : {&a, &b})
*i = 0;
Другой альтернативой могло бы быть использование std::reference_wrapper
, но в этом случае потребовался бы вызов .get()
или явный листинг static_cast<int&>
:
for (auto& i : {std::ref(a), std::ref(b)})
i.get() = 0;
Учитывая, что std::reference_wrapper
имеет оператор неявного преобразования в T&
, я не удивлюсь, если в каком-то другом контексте вы сможете автоматически запускать неявное преобразование (в отличие от вызова .get()
).
Также обратите внимание, что {a, b}
не является диапазоном чисел от a
до b
, это действительно просто эти два числа. Таким образом, с int a = 0, b = 10
у вас не было бы [0, 10]
, а в списке 0
, а затем 10
.
Если вы хотите иметь "правильные" диапазоны, я рекомендую вам взглянуть на Boost.Range.