C++ 使结构的所有数学运算符操作同一成员
我有一个包含一个double和几个标志的结构,但我想在代码中使用它,就好像它就是那个double一样。有没有一种方法可以简化以下代码,以便在该结构的实例上执行的所有数学运算符都在包含双精度的对象上执行?我的代码运行,但我怀疑C++对于我的问题有一个非常优雅和简短的解决方案。C++ 使结构的所有数学运算符操作同一成员,c++,struct,operators,C++,Struct,Operators,我有一个包含一个double和几个标志的结构,但我想在代码中使用它,就好像它就是那个double一样。有没有一种方法可以简化以下代码,以便在该结构的实例上执行的所有数学运算符都在包含双精度的对象上执行?我的代码运行,但我怀疑C++对于我的问题有一个非常优雅和简短的解决方案。 struct SomeStruct { double value; bool someFlag; bool someOtherFlag; operator double(){return v
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;}
...
}
如果将转换运算符更改为
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;
}
(第二个输出是标志
)
还可以定义
运算符double()const
将我们在评论中的讨论转化为答案
我认为你根本不应该这样做。正如您在评论中提到的,您的结构包含来自声学测量的信息,因此它具有一个值和一个标志,指示噪声测量是否使记录仪器过载。让我将您的结构简化为:
struct Noise
{
double noiseLevel;
bool overload;
};
现在,让我们假设您添加了一个转换运算符,以便获得所提供的轻松和方便。现在您有两个噪声测量值quiet
和loud
loud
设置了过载标志,而quiet
没有设置过载标志。现在,您可以执行这两个操作,读者应该期望产生相同的结果:
loud += quiet;
及
但是,由于您的加法不尊重标志,因此这两个操作会产生不同的值。在第一种情况下,设置了重载
标志,而在第二种情况下则不设置。在我看来,这是一种非常令人不安的行为。因此,我建议您实现自己的、类型相关的运算符,以自然方式保留overlad
标志,例如
Noise& operator+=(Noise& lhs, const Noise& rhs)
{
lhs.value += rhs.value;
lhs.overload |= rhs.overload;
return lhs;
}
因此,任何计算的结果(其中一个成员设置了重载标志)也设置了重载标志。您的转换运算符将允许在没有运算符重载的情况下执行此操作。也许可以解决您的问题。如果此操作甚至编译,它也不会执行您认为它会执行的操作。您的
struct
不包含名为value
的成员,因此对该成员的所有引用都将引用名为value
或其他的全局变量,并且这些运算符中似乎只有一个会修改您的struct
,这对于运算符语义来说非常奇怪……您的结构是什么?你为什么要这样做?不,我可以理解在你的计算中仍在使用,但正如你设计的那样,如果我们有两个样本A
和B
,并且A
被重载,但是B
没有,那么A+=B
被重载,但是B+=A
没有。这是令人不安的行为。我认为您应该编写自己的函数,并且在任何情况下,都应该复制重载标志的最坏情况。回答这个问题时不需要,但我也会添加一个const
重载。我可能遗漏了一些明显的内容,但标准中的哪个规则说x
将被初始化为(0,false)
(与具有不确定值相反)?@T.C.:抱歉,添加了显式构造函数。我强烈建议您不要这样做。这种类型的隐式转换是一个随时可能发生的意外。您认为自己很聪明,而且它在一段时间内工作得很好,但最终它变成了一个您不想陷入的兔子洞。@JackAidley想举一个错误的例子吗?
quiet += loud;
Noise& operator+=(Noise& lhs, const Noise& rhs)
{
lhs.value += rhs.value;
lhs.overload |= rhs.overload;
return lhs;
}