На что расширяется a * = b + c? - PullRequest
3 голосов
/ 14 марта 2011

Изучая стандарт, не было информации о том, как это будет расширяться.Я попробовал это в Visual Studio 2008, и он делает a = a * (b + c);Гарантирует ли стандарт, что он всегда будет расширяться, а не a = a * b + c?Было ли это всегда способом, которым выражение расширялось для всех стандартных версий c ++?

Спасибо.

Ответы [ 6 ]

16 голосов
/ 14 марта 2011

Да, это гарантировано.

a::operator*=(b + c);

РЕДАКТИРОВАТЬ:

Приоритет не указан в хорошей таблице в стандарте, есть сноска к 5/4 высказывание:

Приоритетоператоров не указывается напрямую, но может быть получен из синтаксиса.

Таблица C ++ Reference верна.

6 голосов
/ 14 марта 2011

Операторы, подобные =, *=, etc., имеют (почти) наименьший приоритет (см. Эту ссылку ).

Это означает, что любые выражения, которые вы располагаете справа от оператора присваивания, эти выражениябудет оцениваться первым.Затем результат оценки будет присвоен переменной слева от оператора присваивания (умножение по ходу, в случае *=).

5 голосов
/ 14 марта 2011

a *= b + c не «расширяется» ни к чему, *= не является макросом препроцессора.

0 голосов
/ 20 марта 2011

* = это отдельный оператор.Для всех встроенных функций он делает то же самое, что и умножение и присваивание, и если вы когда-либо определяете его для одного из ваших собственных классов, вы действительно ДОЛЖНЫ заставить его делать то же самое по очевидным причинам.Тем не менее, вы бы НЕ ДОЛЖНЫ.

То есть * = - это свой собственный оператор со своим собственным приоритетом, и внутри он будет представлен как «умножение, затем присвоение», но ни в коем случае не являетсяСтрока, когда-либо повторно анализируемая с помощью операторов умножения и присваивания в.

Учитывая это, существует два способа, которыми можно проанализировать строку:

  1. Как a * = (b + c) (должен иметь тот же результат, что и a = a * (b + c) для любых нормальных типов)
  2. As (a * = b) + c (что при условии, что этоавтономный оператор, умножит a на b, присвоит результат a. Затем он умножит новое значение на c, но отбросит результат)

Таким образом, выможно видеть, что нет прецедента, который заставил бы его делать «a = (a * b) + c», чего вы и боялись.

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

Легко проверить приоритет, найдя таблицу, например:

http://www.cppreference.com/wiki/language/operator_precedence

Я не помнювсе детали, так что хорошо проверить, если вы не уверены между похожими операторами, но вы можете сделать большую часть этого, помня общие принципы, подобные этому.

0 голосов
/ 14 марта 2011

*= - собственный оператор. Это должно равняться тем же постусловиям, что и при написании a = a * (b + c), если последнее допустимо, но не гарантируется использование того же пути выполнения для достижения этого.

+ будет иметь более высокий приоритет, чем *=, поэтому гарантируется, что b + c будет оцениваться первым, даже если a относится к типу класса, а *= является перегрузкой.

0 голосов
/ 14 марта 2011

Да, по модулю какая-то неясная ошибка компилятора, правая сторона всегда оценивалась как единое целое.

...