【发布时间】:2021-02-09 04:06:21
【问题描述】:
我的代码介于 c++17 和 c++20 之间。具体来说,我们在 GCC-9 和 clang-9 上启用了 c++20,它只是部分实现。
在代码中,我们有相当大的多态类型层次结构,如下所示:
struct Identifier {
virtual bool operator==(const Identifier&other) const = 0;
};
struct UserIdentifier : public Identifier {
int userId =0;
bool operator==(const Identifier&other) const override {
const UserIdentifier *otherUser = dynamic_cast<const UserIdentifier*>(&other);
return otherUser && otherUser->userId == userId;
}
};
struct MachineIdentifier : public Identifier {
int machineId =0;
bool operator==(const Identifier&other) const override {
const MachineIdentifier *otherMachine = dynamic_cast<const MachineIdentifier*>(&other);
return otherMachine && otherMachine->machineId == machineId;
}
};
int main() {
UserIdentifier user;
MachineIdentifier machine;
return user==machine? 1: 0;
}
我们现在正在迁移到 GCC-10 和 clang-10,但由于某些原因,我们仍然需要在版本 9 上工作(好吧,至少是 clang-9,因为这是 android NDK 目前所拥有的)。
上述代码停止编译,因为实施了有关比较运算符的新规则。可逆运算符== 会导致歧义。我不能使用 spaceship 运算符,因为它没有在版本 9 中实现。但我在示例中省略了这一点 - 我假设任何适用于 == 的东西都适用于其他运算符。
所以: 在 c++20 中使用多态类型实现比较运算符的推荐方法是什么?
【问题讨论】:
-
您确定所有
dynamic_cast的用法吗?这与多态性 IMO 完全相反。此外,它还会产生额外的运行时影响。当然,这里有避免 RTTI 的方法。 -
我担心这种方法是
a == b可能不等同于b == a。 Example -
我听到了,我也不太喜欢这种设计。 @FrançoisAndrieux 每种类型只能与相同类型的其他类型比较。我认为它应该是等价的,只要层次结构的叶子具有具体的运算符实现并且它们的行为都如示例所示。
-
@MateuszL 在这种情况下,将
final添加到叶类以及对该效果的注释可能有助于避免错误。 -
这些真的是多态的吗?您是否有您不知道具体类型的
Identifiers 向量?还是Identifier只是通用代码的存储库?对于curiously recurring template pattern,这似乎是一个不错的应用程序
标签: c++ polymorphism comparison c++20 comparison-operators