Ответ 1
Вопрос 1
Правило о невязанных временных значениях для lvalues не обеспечивает безопасность с использованием железа. Он предотвращает часть этого класса ошибок, но не всех. Я подозреваю, что для предотвращения всех таких ошибок понятие "временность" должно быть включено в систему типов, как и const
. Тогда вы можете "отбросить временность" в тех случаях, когда вы знаете, что вы не сохраните ссылку дольше, чем срок ее действия. Комитет решил, что правильное правило, которое у нас есть, того стоит, по-видимому, они также решили, что дальнейшие усилия не стоят того.
В другом примере vector<int>(4)[0]
также возвращает значение l, даже если вызов operator[]
был сделан во временное. Из-за этого стандарт не собирается запрещать создание временных векторов, и я не вижу, чтобы он также запрещал временные массивы. ОК, поэтому vector
является определяемым пользователем типом, тогда как массивы встроены, но, кроме того, я думаю, что ситуации похожи.
Если вы используете массивы вообще, и особенно временные, то в какой-то степени стандарт думает, что вы получаете то, что заслуживаете. Он не собирается запрещать временные массивы только потому, что можно получить lvalue из одного.
Я думаю, что у вас есть реальная общая точка. Вероятно, подстрочный индекс можно было бы более безопасно определить в массиве rvalues, поскольку компилятор имеет необходимую информацию. Он может оценивать значение rvalue, значение которого соответствует значению соответствующего элемента массива. Это может быть запутанным или неудобным, поскольку оно не согласуется с обычными выражениями в индексе, но было бы безопаснее:-) Если вы пишете struct A {int a;}
, тогда A().a
является rvalue, поэтому я не думаю, что это было бы полностью чтобы применить этот принцип к массивам. Разумеется, это будет потрясающее изменение.
Вопрос 2
Вы не используете индекс в списке с привязкой к init-init. Вы используете его на временной основе, которая, как оказалось, была построена с использованием синтаксиса инициализатора нового стиля. То есть ваше выражение анализирует (intArray{1, 2, 3, 4})[1]
, а не intArray({1, 2, 3, 4}[1])
.