|
|
Здесь определяются синтаксис, порядок вычисления и назначение
выражений. Выражение - это последовательность операций и операндов,
которая задает вычисление. Вычисление может выдавать в качестве
результата значение и может вызывать побочные эффекты.
Операции могут быть перегружены, т.е. им может быть приписано значение,
когда они применяются к выражениям типа класс ($$R.9). Применение
перегруженных операций преобразуется в вызовы функций в соответствии
с описанием в $$R.13.4. Перегруженные операции подчиняются
синтаксическим правилам, определенным в этом разделе, но требования
к типу операнда, адресу и порядку вычисления заменяются на правила
вызова функции. Соотношения между операциями, типа ++a означает
a+=1, не гарантируются для перегруженных операций ($$R.13.4).
В этом разделе описано применение операций к типам, для которых
они не являются перегруженными. Перегрузка операций не может изменить
правила применения операций к типам, для которых такое применение
предусмотрено в самом языке.
Порядок вычисления подвыражений определяется приоритетом и порядком
применения операций. Обычные математические правила ассоциативности
и коммутативности операций действуют только, если операции
действительно ассоциативны или коммутативны. За исключением
оговоренных случаев порядок вычисления операндов конкретной операции
неопределен. В частности, если в выражении значение изменяется
дважды, результат выражения неопределен, если только порядок
выполнения не обеспечивается самими операциями, например:
i = v[i++]; // значение `i' неопределённое
i=7,i++,i++; // `i' становиться 9
Реакция на переполнение и деление на нуль при вычислении выражения
зависит от реализации. В большинстве существующих реализаций С++
игнорируется переполнение целых. Реакция на деление на нуль и
ошибки операций над числами с плавающей точкой варьируется от
машины к машине и обычно связана с соответствующими библиотечными
функциями.
Кроме оговоренных случаев, операнды типа const T, volatile T,
T&, const T& и volatile T& можно использовать, как если бы они
имели тип просто T. Аналогично, операнды типа T* const, T*volatile
можно использовать, как если бы они имели тип просто T*, за
исключением оговоренных случаев. Аналогично, просто тип T можно
использовать всюду, где требуется тип volatile T или const T.
Эти правила может применять в комбинации, так что const T* volatile
можно использовать там, где требуется T*, за исключением оговоренных
случаев. При рассмотрении разрешения перегрузки ($$R.13.2) такое
использование операций не считается стандартным преобразованием
операндов.
Если выражение имеет тип "ссылка на T" ($$R.8.2.2, $$R.8.4.3),
значение выражение есть объект типа "T", на который настроена
ссылка. Выражение является адресом. Ссылку можно представлять как
имя объекта.
Допустимы определенные пользователем преобразования объектов
класса в (и обратно) основные типы, указатели и т.д. ($$R.12.3)
Если они недвусмысленны ($$R.13.2), такие преобразования могут
применяться транслятором всегда, когда появляется объект типа класса
в качестве операнда операции, в качестве инициализирующего
выражения ($$R.8.4), в качестве выражения, задающего условие ($$R.6.4),
или в качестве выражения, используемого в операторе цикла ($$R.6.5),
или в качестве значения, возвращаемого функцией ($$R.6.6.3),
или в качестве параметра функции ($$R.5.2.2).
| |