Создание всех математических операторов структуры, управляющих одним и тем же членом

У меня есть структура, содержащая двойной и несколько флагов, но я хотел бы использовать ее в своем коде, как если бы это был только этот двойной. Есть ли способ упростить следующий код, чтобы все математические операторы, выполняемые в экземпляре этой структуры, выполнялись в содержащем двойнике? Мой код работает, но я подозреваю, что С++ имеет очень элегантное и короткое решение для моей проблемы.

struct SomeStruct
{
    double value;
    bool someFlag;
    bool someOtherFlag;

    operator double(){return value;}

    void operator=(double newValue){value = newValue;}
    void operator+=(double valueToAdd){value += valueToAdd;}
    void operator-=(double valueToSubtract){value-= valueToSubtract;}
    void operator/=(double divisor){value /= divisor;}
    void operator*=(double multiplier){value *= multiplier;}
    double operator+(double valueToAdd){return value + valueToAdd;}
    ...
}

Ответы

Ответ 1

Если вы измените оператор преобразования на operator double &, вы получите все операторы на double бесплатно, за исключением operator=:

#include <iostream>

struct Foo {
    double d;
    bool flag;

    Foo() : d(0), flag(false) {}

    operator double &() { return d; }
};

int main()
{
    Foo x;  // initialized to (0, false)
    x.flag = true;
    x += 1.1;
    std::cout << x.d << " " << x.flag << std::endl;
    x *= 2;
    std::cout << x.d << " " << x.flag << std::endl;
}

печатает

1.1 1
2.2 1

(второй вывод - flag).

Возможно, стоит также указать operator double() const.

Ответ 2

Чтобы включить наше обсуждение в комментарии в ответ...

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

struct Noise
{
  double noiseLevel;
  bool overload;
};

Теперь предположим, что вы добавляете в оператор преобразования, чтобы получить удобство и удобство. Теперь у вас есть два измерения шума quiet и loud. loud имеет флаг перегрузки, а quiet - нет. Теперь вы можете сделать эти две операции, которые читатель должен ожидать получить равным результатом:

loud += quiet;

и

quiet += loud;

но поскольку ваше добавление не соблюдает флаг, две операции производят разные значения. В первом случае флаг overload устанавливается, а во втором - нет. Мне кажется, это очень тревожное поведение. Вместо этого я рекомендую вам реализовать собственные, поддерживающие тип, операторы, которые естественным образом сохраняют флаг overlaud, например.

Noise& operator+=(Noise& lhs, const Noise& rhs)
{
  lhs.value += rhs.value;
  lhs.overload |= rhs.overload;
  return lhs;
}

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