+ = перегрузка и каскадирование оператора?

Для образовательных целей я хочу перегрузить и использовать оператор + = в каскаде.

class a {
    public:
        a();
        a& operator+= (float f);
    private:
        float aa;
}

a() {
    aa = 0;
}

a& operator+= (float f) {
    aa += f;
    return *this;
}

a b;
b += 1.0; // Works.
b += 1.0 += 1.0; // Error : Expression must be a modifiable lvalue.

Я не понимаю, почему приведенное выше не работает (кроме возможных синтаксических ошибок - не пыталось скомпилировать этот примерный код). Возвращая * это в перегруженном операторе + = метод, я ожидал бы, что второй + = 1.0 будет вызван на объект b, no?

Спасибо.

Ответы

Ответ 1

b += 1.0 += 1.0;

Ассоциативность для += является справа налево. Таким образом, вышесказанное интерпретируется как:

(b += (1.0 += 1.0));

Это имеет смысл? НЕТ.

Чтобы заставить его работать, вам нужно написать его как:

(b += 1.0) += 1.0;

Надеюсь, что это поможет.

Ответ 2

Обратите внимание, что для того, чтобы иметь class a с наименьшим количеством сюрпризов для своих пользователей, лучше всего также определить функцию-член

a& operator+=(a const&); 

а также функции, не являющиеся членами

a operator+(a const&, a const&); 
a operator+(a const&, float); 
a operator+(float, a const&);

каждый из которых определяется в терминах одной из перегрузок элементов operator+=. Затем вы можете написать

a1 += b1 + c1; 

где a1 имеет тип a, переменные b1, c1 могут быть либо float, либо a. См. этот вопрос из для более подробной информации.

Ответ 3

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

class a {
    public:
        a();
        a(float f);
        a& operator+= (float f);
        operator float() const;
    private:
        float aa;
};

a::a() {
    aa = 0;
}

a::a(float f) {
    aa = f;
}

a& a::operator+= (float f) {
    aa += f;
    return *this;
}

a::operator float() const {
    return aa;
}

int main()
{
    a b = 1.0;
    b += 1.0; // Works.
    b += (a)1.0 += 1.0; // Works.
}

или, может быть, лучше без оператора преобразования, но с operator+=(const a&);

class a {
    public:
        a();
        a(float f);
        a& operator+= (float f);
        a& operator+= (const a & x);
    private:
        float aa;
};

a::a() {
    aa = 0;
}

a::a(float f) {
    aa = f;
}

a& a::operator+= (float f) {
    aa += f;
    return *this;
}

a& a::operator+= (const a & x) {
    aa += x.aa;
    return *this;
}

int main()
{
    a b = 1.0;
    b += 1.0; // Works.
    b += (a)1.0 += 1.0; // Works.
}