C++ 重载比较运算符失败[C+;+;11]
我有一个带有两个重载比较运算符(运算符==)的RGB颜色类。 一个用于自类型,一个用于int(十六进制) 我不知道会发生什么。比较返回false,但如果我取消对定义中std::cout行的注释,则函数将按预期工作并返回true 这也没有问题:C++ 重载比较运算符失败[C+;+;11],c++,c++11,comparison,compare,operator-overloading,C++,C++11,Comparison,Compare,Operator Overloading,我有一个带有两个重载比较运算符(运算符==)的RGB颜色类。 一个用于自类型,一个用于int(十六进制) 我不知道会发生什么。比较返回false,但如果我取消对定义中std::cout行的注释,则函数将按预期工作并返回true 这也没有问题: RGB a = 0x555555; RGB b = 0x555555; bool equals = (a == b); // returns true 有人有想法吗?你知道你的 RGB::operator=()从未被调用 RGB a = 0x555555
RGB a = 0x555555;
RGB b = 0x555555;
bool equals = (a == b); // returns true
有人有想法吗?你知道你的
RGB::operator=()
从未被调用
RGB a = 0x555555;
调用RGB的构造函数,该构造函数接受int
。
如果没有定义任何这样的构造函数,代码将无法编译,因此,给出的代码段是不完整的。但是,
RGB a;
a = 0x555555;
默认值构造一个RGB
实例并调用RGB::operator=(int)。
我用clang++和g++两种语言试过你的代码,比较结果总是
true`
代码在注释为in或out的std::cout
行中的行为不同,这一点非常奇怪。这可能是一些优化问题和浮点比较,这是邪恶的:谷歌的“浮点比较”看看为什么。
为了验证这一点,我将向它附加一个调试器,并查看r
、rr
、g
、gg
、b
和bb
的实际(十六进制)值
请注意,您的分配操作员应该返回对该
*的引用,而不是副本。您是否知道
RGB::operator=()
从未被调用
RGB a = 0x555555;
调用RGB的构造函数,该构造函数接受int
。
如果没有定义任何这样的构造函数,代码将无法编译,因此,给出的代码段是不完整的。但是,
RGB a;
a = 0x555555;
默认值构造一个RGB
实例并调用RGB::operator=(int)。
我用clang++和g++两种语言试过你的代码,比较结果总是
true`
代码在注释为in或out的std::cout
行中的行为不同,这一点非常奇怪。这可能是一些优化问题和浮点比较,这是邪恶的:谷歌的“浮点比较”看看为什么。
为了验证这一点,我将向它附加一个调试器,并查看r
、rr
、g
、gg
、b
和bb
的实际(十六进制)值
请注意,赋值运算符应返回对该
*的引用,而不是副本。未经优化,不应获得浮点比较效果。这是因为在这两种情况下,您具有相同的功能
如果不进行优化,以下是正确的:
float func(float);
float a = ...;
func(a) == func(a); //< always true
例如,它可以在优化后做一些事情:
255.0f * r == (X)
这现在确实会受到浮点比较效果的影响。然而,通过在中间引入STDUT,你会迫使它对表达式进行更接近于它们被写入的方式的评估,这又会使你回到同一个函数对自身进行评估的真实性。
您可以更改类的定义以将值存储为整数,并仅在需要浮点时转换为浮点,或者存储十六进制表示和浮点,并使用十六进制进行比较。或者,您可以使用大于/小于而不是双等于进行比较,测试两个浮点值之间的距离是否在1/255以内。例如,类似这样的事情:
return (abs(r - rr) < 1/255.0f && ...);
bool operator==(const unsigned int hex) __attribute__((optimize("O0")));
return(abs(r-rr)<1/255.0f&&&;
未经优化,不应获得浮点比较效果。这是因为在这两种情况下,您具有相同的功能
如果不进行优化,以下是正确的:
float func(float);
float a = ...;
func(a) == func(a); //< always true
例如,它可以在优化后做一些事情:
255.0f * r == (X)
这现在确实会受到浮点比较效果的影响。然而,通过在中间引入STDUT,你会迫使它对表达式进行更接近于它们被写入的方式的评估,这又会使你回到同一个函数对自身进行评估的真实性。
您可以更改类的定义以将值存储为整数,并仅在需要浮点时转换为浮点,或者存储十六进制表示和浮点,并使用十六进制进行比较。或者,您可以使用大于/小于而不是双等于进行比较,测试两个浮点值之间的距离是否在1/255以内。例如,类似这样的事情:
return (abs(r - rr) < 1/255.0f && ...);
bool operator==(const unsigned int hex) __attribute__((optimize("O0")));
return(abs(r-rr)<1/255.0f&&&;
谢谢大家,问题在于JoshG79所说的优化。
为了解决这个问题,首先我尝试将计算存储在易失性变量中,这可能会阻止它们进行优化,但它们会做一些其他事情,并导致开销。所以我决定使用
因此,标头中的函数声明如下所示:
return (abs(r - rr) < 1/255.0f && ...);
bool operator==(const unsigned int hex) __attribute__((optimize("O0")));
现在一切都很好,工作起来很有魅力。谢谢大家,问题在于JoshG79所说的优化。 为了解决这个问题,首先我尝试将计算存储在易失性变量中,这可能会阻止它们进行优化,但它们会做一些其他事情,并导致开销。所以我决定使用 因此,标头中的函数声明如下所示:
return (abs(r - rr) < 1/255.0f && ...);
bool operator==(const unsigned int hex) __attribute__((optimize("O0")));
现在一切都很好,工作起来很有魅力。为什么要使用浮点作为RGB值的基础类型?因为它简化了颜色的计算(混合、颜色空间之间的转换等),OpenGL接受颜色组件作为浮点。@user2430597请发布
RGB::RGB(int hex)
的定义。如果只使用已发布的运算符,则会显示代码。RGB::RGB(int hex){setHex(hex);}内联void RGB::setHex(无符号十六进制){r=(float)(hex>>16&0xFF)/255.0f;g=(float)(hex>>8&0xFF)/255.0f;b=(float)(hex&0xFF)/255.0f;}可能与您为什么要使用这些运算符有关