Как возвращаемый объект может быть назначен? - PullRequest
18 голосов
/ 12 января 2012

В действующем C ++, пункт 3, Скотт Мейерс предлагает перегрузить operator* для класса с именем Rational:

    class Rational { ... };
    const Rational operator*(const Rational& lhs, const Rational& rhs);

Причина, по которой возвращаемое значение является const -качественным, объясняется в следующей строке: если бы это было не const, программисты могли бы написать такой код:

    (a * b) = c;

или, более вероятно:

     if (a*b = c)

Достаточно справедливо. Теперь я запутался, когда подумал, что возвращаемое значение функции, в данном случае оператор *, является значением r, поэтому не может быть назначено. Я считаю, что это не присваивается, потому что если бы у меня было:

    int foo();
    foo() += 3;

, который не скомпилируется с invalid lvalue in assignment. Почему этого не происходит здесь? Может кто-нибудь пролить свет на это?

РЕДАКТИРОВАТЬ : Я видел много других тем по этому самому предмету Скотта Мейерса, но ни одна из них не решала проблему с ценностями, которую я здесь выявил.

1 Ответ

30 голосов
/ 12 января 2012

Дело в том, что для типов классов a = b - это просто сокращение от a.operator=(b), где operator= - функция-член. И функции-члены могут вызываться по rvalues.

Обратите внимание, что в C ++ 11 вы можете запретить это, сделав operator= lvalue-only:

class Rational
{
public:
  Rational& operator=(Rational const& other) &;
  // ...
};

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

...