C++17 operator==() and operator!=() code fails with C++20(C++17运算符==()和运算符!=()代码在C++20中失败)
问题描述
我有以下示例代码:
#include <assert.h>
struct Base
{
bool operator==(const Base& rhs) const
{
return this->equalTo(rhs);
}
virtual bool equalTo(const Base& rhs) const = 0;
};
inline bool operator!=(const Base& lhs, const Base& rhs)
{
return !(lhs == rhs);
}
struct A : public Base
{
int value = 0;
bool operator==(const A& rhs) const
{
return (value == rhs.value);
}
virtual bool equalTo(const Base& rhs) const
{
auto a = dynamic_cast<const A*>(&rhs);
return (a != nullptr) ? *this == *a : false;
}
};
class A_1 : public A
{
virtual bool equalTo(const Base& rhs) const
{
auto a_1 = dynamic_cast<const A_1*>(&rhs);
return (a_1 != nullptr) ? *this == *a_1 : false;
}
};
int main()
{
A_1 a_1;
a_1.value = 1;
// Make sure different types aren't equal
A a;
a.value = 1;
assert(a_1 != a);
}
当我用C++17编译时,一切都很好(如所需,没有断言)。使用C++20生成相同的代码会导致触发Assert。
在使用C++20编译时,如何使这些现有代码工作?如果我用C++20放大警告,我会得到'operator !=': unreferenced inline function has been removed;我怀疑这一切都与operator<=>()有某种关系。
这真的是从C++17到C++20的已知/所需的重大更改吗?
推荐答案
在C++17中,行
assert(a_1 != a);
调用operator!=(const Base&, const Base&),因为它当然是唯一的候选者。然后调用a_1->equalTo(a),它试图将a向下转换为A_1,这在您的逻辑中会给出FALSE。因此a_1 != a评估为true。
在C++20中,我们现在额外考虑根据
==重写的候选对象。因此,现在我们有三位候选人:
Base::operator==(const Base&) const(重写)A::operator==(const A&) const(重写)bool operator!=(const Base&, const Base&)
a_1 != a计算为!((const A&)a_1 == a),这为您提供了不同的答案。
然而,您的操作符从根本上说是失败的。即使在C++17中,我们也有这样的场景:a_1 != a计算为true,而a != a_1计算为false。这基本上是试图像这样做动态相等的固有问题:this->equalTo(rhs)和rhs.equalTo(*this)实际上可能会做不同的事情。因此,这个问题与其说是C++20比较问题,不如说是一个基本的设计问题。
这篇关于C++17运算符==()和运算符!=()代码在C++20中失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:C++17运算符==()和运算符!=()代码在C++20中失败
基础教程推荐
- C++结构和函数声明。为什么它不能编译? 2022-11-07
- 常量变量在标题中不起作用 2021-01-01
- 如何通过C程序打开命令提示符Cmd 2022-12-09
- 静态库、静态链接动态库和动态链接动态库的 .lib 文件里面是什么? 2021-01-01
- 在 C++ 中计算滚动/移动平均值 2021-01-01
- 如何将 std::pair 的排序 std::list 转换为 std::map 2022-01-01
- 这个宏可以转换成函数吗? 2022-01-01
- 我有静态或动态 boost 库吗? 2021-01-01
- 如何在 C++ 中初始化静态常量成员? 2022-01-01
- 如何检查GTK+3.0中的小部件类型? 2022-11-30
