我有一些代码,处于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当前的版本)。
上述代码停止编译是因为实施了关于比较运算符的新规则。可逆运算符==会导致歧义。我不能使用宇宙飞船操作符,因为其在版本9中没有实现。但我在示例中省略了它——我假设任何与==一起使用的内容都可以与其他运算符一起使用。
那么:
c++20中使用多态类型实现比较运算符的推荐方法是什么?
dynamic_cast
使用是必需的吗?在我看来,它与多态的本质相反。此外,它会导致额外的运行时开销。肯定有方法可以避免使用 RTTI。 - goodvibrationa == b
可能不等同于b == a
。示例 - François Andrieuxfinal
添加到叶子类,并附上相应的注释可能有助于避免错误。 - François AndrieuxIdentifier
的向量,其中您不知道具体类型?还是Identifier
只是一个用于存储公共代码的仓库?这似乎是使用好奇的递归模板模式的不错应用。 - trent