Какова категория значений операндов операторов С++, когда они не указаны?
ПОМЕЩЕНИЕ:
Стандарт С++ 11 классифицирует выражения в три непересекающиеся категории значения: lvalues, xvalues и prvalues (§ 3.10/1). Объяснение того, какие категории значений доступны, например здесь.
Я изо всех сил пытаюсь выяснить, каковы требования различных операторов к категории значений их операндов. В пункте 3.10/1 указывается:
[...] Каждое выражение относится к одной из фундаментальных классификаций в этой таксономии: lvalue, xvalue или prvalue. Это свойство выражения называется его категорией значений. [Примечание. Обсуждение каждого встроенного оператора в Параграф 5 указывает категорию значения, которое он дает, и категории значений операндов, которые он ожидает. Например, встроенные операторы присваивания ожидают, что левый операнд является lvalue и что правый операнд является значением prvalue и дает значение lvalue в качестве результата. Определяемые пользователем операторы являются функциями, а категории ожидаемых значений и доходности определяются их параметрами и типами возврата. -end note]
Несмотря на то, что вышеприведенная нота, пункт 5 не всегда очень понятен в отношении категории операндов операторов. Это, например, все, что сказано о категории значений операндов оператора присваивания (параграф 5.17/1):
Оператор присваивания (=) и составные операторы присваивания все группы справа налево. Все требуют модифицируемого значения lvalue в качестве своего левого операнда и возвращают lvalue, ссылаясь на левый операнд. Результатом во всех случаях является бит-поле, если левым операндом является бит-поле. Во всех случаях назначение упорядочивается после вычисления значения правого и левого операндов и перед вычислением значения выражения присваивания. Что касается вызова функции с неопределенной последовательностью, то операция составного присвоения представляет собой единую оценку. [Примечание. Следовательно, вызов функции не должен вмешиваться между преобразованием lvalue-to-rvalue и побочным эффектом, связанным с любым отдельным оператором присваивания. -end note]
Как насчет правильных операндов?
Слова "rvalue" и "lvalue" больше не встречаются во всем разделе 5.17. Хотя в примечании в параграфе 3.10/1 четко указывается, что встроенные операторы присваивания ожидают prvalue как правый операнд, это явно не упоминается в разделе 5.17. Даже последнее замечание 5.17/1, в котором упоминаются преобразования lvalue-to-rvalue, похоже, подразумевает, что rvalues ожидаются каким-то образом (что означает необходимость преобразования в противном случае?), Но примечания в целом не являются нормативными.
Разделы, относящиеся к другим операторам, включая мультипликативные и аддитивные операторы, обычно молчат в категории значений их операндов. Я не смог найти "стандартную инструкцию" в Стандарте, заявив, что, если не указано иное, операнды встроенных операторов имеют значения r. Следовательно, вопрос.
Вопрос:
- Какова категория значений правильного операнда оператора присваивания; и, в более общем плане,
- Как определить категорию значений операнда операнда, если это не указано? Является ли это безусловным (что означает, что любая категория ценностей принимается)? Если да, то почему преобразования lvalue-to-rvalue когда-либо применяются в выражении присваивания?
Приветствуются ссылки на стандарт С++ 11.
Ответы
Ответ 1
Да, он не указан и был рассмотрен до. В принципе, каждый раз, когда требуется выражение lvalue, перечисляется, поэтому мы предполагаем, что каждый другой операнд должен быть выражением prvalue.
Итак, чтобы ответить на ваши вопросы:
- Значение.
- Если он не указан, это значение prile.
Заметка, указанная в связанном ответе, кажется, несколько раз изменилась. Цитата из § 3.10 стандарта С++ 11 выглядит следующим образом (и в текущее время в последнем черновике):
[Примечание. Обсуждение каждого встроенного оператора в разделе 5 указывает категорию значения, которое оно дает, и категории значений для операндов, которые он ожидает. Например, встроенные операторы присваивания ожидают, что левый операнд будет lvalue и что правый операнд является prvalue и дает результат lvalue в качестве результата. Определяемые пользователем операторы являются функциями, а категории ожидаемых значений и доходности определяются их параметрами и типами возврата. - конечная нота]
Здесь он даже явно говорит, что операторы присваивания ожидают, что правый операнд будет значением prvalue. Конечно, это примечание и поэтому является ненормативным.