Читать «Справочное руководство по C++» онлайн - страница 13

Бьярн Страустрап

Отметим, что указатель на член не является указателем на объект или указателем на функцию и правила преобразований таких указателей не применимы для указателей на члены. В частности указатель на член нельзя преобразовать в void*.

R.5 Выражения

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

Операции могут быть перегружены, т.е. им может быть приписано значение, когда они применяются к выражениям типа класс (§R.9). Применение перегруженных операций преобразуется в вызовы функций в соответствии с описанием в §R.13.4. Перегруженные операции подчиняются синтаксическим правилам, определенным в этом разделе, но требования к типу операнда, адресу и порядку вычисления заменяются на правила вызова функции. Соотношения между операциями, типа ++a означает a+=1, не гарантируются для перегруженных операций (§R.13.4).

В этом разделе описано применение операций к типам, для которых они не являются перегруженными. Перегрузка операций не может изменить правила применения операций к типам, для которых такое применение предусмотрено в самом языке.

Порядок вычисления подвыражений определяется приоритетом и порядком применения операций. Обычные математические правила ассоциативности и коммутативности операций действуют только, если операции действительно ассоциативны или коммутативны. За исключением оговоренных случаев порядок вычисления операндов конкретной операции неопределен. В частности, если в выражении значение изменяется дважды, результат выражения неопределен, если только порядок выполнения не обеспечивается самими операциями, например:

i = v[i++]; // the value of `i' is undefined

i=7, i++, i++; // `i' becomes 9

Реакция на переполнение и деление на нуль при вычислении выражения зависит от реализации. В большинстве существующих реализаций C++ игнорируется переполнение целых. Реакция на деление на нуль и ошибки операций над числами с плавающей точкой варьируется от машины к машине и обычно связана с соответствующими библиотечными функциями.

Кроме оговоренных случаев, операнды типа 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) такое использование операций не считается стандартным преобразованием операндов.