Jac*_*own 2 c++ operator-overloading 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);
}
Run Code Online (Sandbox Code Playgroud)
当我使用 C++17 编译时,一切都很好(根据需要,没有断言)。使用 C++20 构建相同的代码会导致断言触发。
使用 C++20 编译时如何使现有代码正常工作?如果我使用 C++20 加大警告力度,我会得到'operator !=': unreferenced inline function has been removed;我怀疑这一切都与某种有关operator<=>()。
这真的是从 C++17 到 C++20 的已知/期望的重大更改吗?
Bar*_*rry 10
在 C++17 中,该行
assert(a_1 != a);
Run Code Online (Sandbox Code Playgroud)
调用operator!=(const Base&, const Base&),因为当然,它是唯一的候选者。然后调用a_1->equalTo(a),它尝试向下转换a为 an 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&)其中,(2) 是最佳候选,因为它与两个参数更匹配。所以a_1 != a评估为!((const A&)a_1 == a),这会给你一个不同的答案。
然而,你的操作员从根本上被破坏了。即使在 C++17 中,我们也有这样的场景:a_1 != a评估为truewhilea != a_1评估为false。这基本上是尝试像这样进行动态平等的固有问题:this->equalTo(rhs)并且rhs.equalTo(*this)实际上可能会做不同的事情。因此,这个问题与其说是 C++20 比较问题,不如说是基本设计问题。
| 归档时间: |
|
| 查看次数: |
476 次 |
| 最近记录: |