Операции присваивания
Есть много операций присваивания, все группируют слева направо. Все в качестве левого операнда требуют lvalue, и тип выражения присваивания тот же, что и у его левого операнда. Это lvalue не может ссылаться на константу (имя массива, имя функции или const). Значением является значение, хранящееся в левом операнде после выполнения присваивания.
выражение_присваивания: выражение операция_присваивания выражение
операция_присваивания: одна из = += -= *= /= %= >>= <<= &= ~= |=
В простом присваивании с = значение выражения замещает собой значение объекта, на который ссылается операнд в левой части. Если оба операнда имеют арифметический тип, то при подготовке к присваиванию правый операнд преобразуется к типу левого. Если аргумент в левой части имеет указательный тип, аргумент в правой части должен быть того же типа или типа, который может быть преобразован к нему, см. здесь. Оба операнда могут быть объектами одного класса. Могут присваиваться объекты некоторых производных классов; см. этот пункт.
Присваивание объекту типа "указатель на ..." выполнит присваивание объекту, денотируемому ссылкой.
Выполнение выражения вида E1 op= E2 можно представить себе как эквивалентное E1 = E1 op (E2); но E1 вычисляется только один раз. В += и -= левый операнд может быть указателем, и в этом случае (интегральный) правый операнд преобразуется так, как объяснялось в #7.4; все правые операнды и не являющиеся указателями левые должны иметь арифметический тип.
Операция запятая
запятая_выражение: выражение , выражение
Пара выражений, разделенных запятой, вычисляется слева направо, значение левого выражения теряется. Тип и значение результата являются типом и значением правого операнда. Эта операция группирует слева направо. В контексте, где запятая имеет специальное значение, как например в списке фактических параметров функции (здесь) и в списке инициализаторов (см. тут), операция запятая, как она описана в этом разделе, может появляться только в скобках; например,
f (a,(t=3,t+2),c)
имеет три параметра, вторым из которых является значение 5.
Перегруженные операции
Большинство операций может быть перегружено, то есть, описано так, чтобы они получали в качестве операндов объекты классов (см. этот пункт). Изменить приоритет операций невозможно. Невозможно изменить смысл операций при применении их к неклассовым объектам. Предопределенный смысл операций = и & (унарной) при применении их к объектам классов может быть изменен.
Эквивалентность операций, применяемых к основным типам (например, ++a эквивалентно a+=1), не обязательно выполняется для операций, применяемых к классовым типам. Некоторые операции, например, присваивание, в случае применения к основным типам требуют, чтобы операнд был lvalue; это не требуется для операций, описанных для классовых типов.
Унарные операции
Унарная операция, префиксная или постфиксная, может быть определена или с помощью функции члена (см. этот раздел), не получающей параметров, или с помощью функции друга (см. здесь), получающей один параметр, но не двумя способами одновременно. Так, для любой унарной операции @, x@ и @x могут интерпретироваться как x.операция@() или операция@(x). При перегрузке операций ++ и -- невозможно различить префиксное и постфиксное использование.
Бинарные операции
Бинарная операция может быть определена или с помощью функции члена (см. #8.5.4), получающей один параметр, или с помощью функции друга (см. этот пункт), получающей два параметра, но не двумя способами одновременно. Так, для любой бинарной операции @, x@y может быть проинтерпретировано как x.операция@(y) или операция@(x,y).
Особые операции
Вызов функции
первичное_выражение ( список_выражений opt )
и индексирование
первичное_выражение [ выражение ]
считаются бинарными операциями. Именами определяющей функции являются соответственно operator() и operator[]. Обращение x(arg) интерпретируется как x.operator()(arg) для классового объекта x. Индексирование x[y] интерпретируется как x.operator[](y). 1 2 3 4 5
8 8 8
| |