Какова категория значений операндов операторов C++, если они не указаны?

ПОМЕЩЕНИЕ:

Стандарт C++11 классифицирует выражения на три категории непересекающихся значений: lvalues, xvalues и prvalues (§ 3.10/1). Объяснение того, что категории значения доступны, например, здесь.

Я пытаюсь выяснить, каковы требования различных операторов к категории значений их операндов. Пункт 3.10/1 определяет:

[...] Каждое выражение принадлежит точно к одной из основных классификаций в этой таксономии: lvalue, xvalue или prvalue. Это свойство выражения называется его категорией значений. [Примечание: обсуждение каждого встроенного оператора в разделе 5 указывает категорию получаемого им значения и категории значений ожидаемых им операндов. Например, встроенные операторы присваивания ожидают, что левый операнд является lvalue, а правый операнд является prvalue, и в результате получается lvalue. Определяемые пользователем операторы являются функциями, а категории значений, которые они ожидают и получают, определяются их параметрами и типами возвращаемых данных. —Конечная записка]

Несмотря на то, что говорится в примечании выше, пункт 5 не всегда очень ясно описывает категорию значений операндов операторов. Это, например, все, что сказано о категории значений операндов оператора присваивания (пункт 5.17/1):

Оператор присваивания (=) и составные операторы присваивания все группы справа налево. Все они требуют изменяемого lvalue в качестве своего левого операнда и возвращают lvalue, ссылаясь на левый операнд. Результатом во всех случаях является битовое поле, если левый операнд является битовым полем. Во всех случаях присваивание выполняется после вычисления значения правого и левого операндов и перед вычислением значения выражения присваивания. Что касается вызова функции с неопределенной последовательностью, операция составного присваивания является единственной оценкой. [Примечание: Поэтому вызов функции не должен вмешиваться между преобразованием lvalue-to-rvalue и побочным эффектом, связанным с каким-либо одним составным оператором присваивания. —Конечная записка]

Как насчет правильных операндов?

Слова "rvalue" и "lvalue" больше не встречаются во всем разделе 5.17. Хотя примечание в п. 3.10/1 прямо указывает на то, что встроенные операторы присваивания ожидают значение prvalue в качестве правого операнда, это явно не упоминается в разделе 5.17. Даже последнее примечание 5.17/1, в котором упоминается преобразование lvalue-в-значение, кажется, подразумевает, что r-значения ожидаются каким-то образом (зачем нужно преобразование в противном случае?), Но примечания в конце концов ненормативны.

Разделы, касающиеся других операторов, включая мультипликативные и аддитивные операторы, как правило, ничего не говорят о категории значений своих операндов. Я не смог найти ни одного "оператора по умолчанию" в Стандарте, утверждающего, что, если не указано иное, операнды встроенных операторов являются значениями. Отсюда и вопрос.

ВОПРОС:

  1. Какова категория значений правого операнда оператора присваивания; и, в более общем плане
  2. Как выяснить категорию значения операнда оператора, если он не указан? Является ли оно неограниченным (имеется в виду, что любая ценностная категория принята)? Если так, почему преобразования lvalue-в-значение должны когда-либо применяться в выражении присваивания?

Ссылки на стандарт C++11 высоко ценятся.

1 ответ

Решение

Да, это плохо определено и было покрыто ранее. По сути, каждый раз, когда требуется выражение lvalue, перечисляется, поэтому мы предполагаем, что каждый другой операнд должен быть выражением prvalue.

Итак, чтобы ответить на ваши вопросы:

  1. Prvalue.
  2. Если это не указано, это prvalue.

Примечание, указанное в связанном ответе, похоже, несколько раз менялось. Цитата из §3.10 стандарта C++11 выглядит следующим образом (и в настоящее время идентична в последнем проекте):

[Примечание: обсуждение каждого встроенного оператора в разделе 5 указывает категорию получаемого им значения и категории значений ожидаемых им операндов. Например, встроенные операторы присваивания ожидают, что левый операнд является lvalue, а правый операнд является prvalue, и в результате получается lvalue. Определяемые пользователем операторы являются функциями, а категории значений, которые они ожидают и получают, определяются их параметрами и типами возвращаемых данных. - конец примечания]

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

Другие вопросы по тегам