8 Expressions [expr]

8.18 Assignment and compound assignment operators [expr.ass]

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

assignment-expression:
	conditional-expression
	logical-or-expression assignment-operator initializer-clause
	throw-expression
assignment-operator: one of
	=  *=  /=  %=   +=  -=  >>=  <<=  &=  ^=  |=

В простом присваивании (=) значение выражения заменяет значение объекта, на который ссылается левый операнд.

Если левый операнд не относится к типу класса, выражение неявно преобразуется (Clause [conv]) в тип cv-unqualified левого операнда.

Если левый операнд относится к типу класса, класс должен быть полным. Присвоение объектам класса определяется оператором присваивания копировать / перемещать ([class.copy], [over.ass]).

[ Note: Для объектов класса, назначение не в общем такой же , как инициализации ([dcl.init], [class.ctor], [class.init], [class.copy]). ]end note

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

Поведение выражения формы E1 op= E2 эквивалентно, за E1 = E1 op E2 исключением того, что E1 оценивается только один раз. В += и -=, E1 должен либо иметь арифметический тип или быть указателем на полностью определенный тип объекта , возможно , CV-квалификации. Во всех остальных случаях E1 должен иметь арифметический тип.

Если значение, хранящееся в объекте, считывается через другой объект, который каким-либо образом перекрывает хранилище первого объекта, то перекрытие должно быть точным, и два объекта должны иметь один и тот же тип, в противном случае поведение не определено. [ Note: Это ограничение применяется к отношениям между левой и правой сторонами операции присваивания; это не утверждение о том, как цель назначения может быть псевдонимом в целом. Смотрите [basic.lval]. ] end note

С braced-init-listправой стороны от

  • присвоение скаляру, и в этом случае список инициализаторов должен иметь не более одного элемента. Значение x = {v}, где T - скалярный тип выражения x, - значение x = T{v}. Смысл в x = {} том x = T{}.

  • присваивание объекту типа класса, и в этом случае список инициализаторов передается в качестве аргумента функции оператора присваивания, выбранной с помощью разрешения перегрузки ([over.ass], [over.match]).

[Example:

complex<double> z;
z = { 1,2 };              // meaning z.operator=({1,2})
z += { 1, 2 };            // meaning z.operator+=({1,2})
int a, b;
a = b = { 1 };            // meaning a=b=1;
a = { 1 } = b;            // syntax error

end example]