Создание всех математических операторов структуры, управляющих одним и тем же членом
У меня есть структура, содержащая двойной и несколько флагов, но я хотел бы использовать ее в своем коде, как если бы это был только этот двойной. Есть ли способ упростить следующий код, чтобы все математические операторы, выполняемые в экземпляре этой структуры, выполнялись в содержащем двойнике? Мой код работает, но я подозреваю, что С++ имеет очень элегантное и короткое решение для моей проблемы.
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;
}
Так, чтобы результат любого вычисления, в котором один элемент имеет флаг перегрузки, также имеет установленный флаг перегрузки.