C++严格弱序派生类
C++ strict weak ordering derived class
我试图在一个子类中实现严格的弱排序,我想把它放在STL集容器中。STL集合使用运算符<以严格的弱排序对其元素进行排序。在我的例子中,我有一个类型层次结构,我不太确定如何为派生类型实现这一点。为此,我制作了一个快速的现场演示,展示了我不确定的地方。我使用一种易于使用的std::tie技术对字段进行排序。我不确定的领域是我应该如何调用超类的运算符<在对派生字段调用std::tie比较之前。
struct Base {
Base(const int& rIntVal, const std::string& rStrVal)
: mIntVal(rIntVal)
, mStrVal(rStrVal)
{}
inline bool operator<(const Base& rhs) const {
return std::tie(mIntVal, mStrVal) < std::tie(rhs.mIntVal, rhs.mStrVal);
}
private:
int mIntVal;
std::string mStrVal;
};
struct Derived : public Base {
Derived(
const int& rIntVal,
const std::string& rStrVal,
const std::string& rOtherStrVal,
const std::string& rOtherStrVal1)
: Base(rIntVal, rStrVal)
, mOtherStrVal(rOtherStrVal)
, mOtherStrVal1(rOtherStrVal1)
{}
inline bool operator<(const Derived& rhs) const {
// not sure what to do here - this is my best guess???
if( Base::operator<(rhs) ) {
return std::tie(mOtherStrVal, mOtherStrVal1) <
std::tie(rhs.mOtherStrVal, rhs.mOtherStrVal1);
} else {
return false;
}
}
private:
std::string mOtherStrVal;
std::string mOtherStrVal1;
};
最好将引用绑定到基类:
bool operator<(const Derived& rhs) const {
return std::tie(static_cast<const Base&>(*this), mOtherStrVal, mOtherStrVal1) <
std::tie(static_cast<const Base&>(rhs), rhs.mOtherStrVal, rhs.mOtherStrVal1);
}
这将首先按超类字段进行比较,然后按子类字段进行对比。
首先,您可以选择让派生字段优先于基本字段,以便首先考虑派生成员,或者您可以给基本字段优先权。该怎么做取决于你的类的含义以及它应该如何排序。
您已经选择先比较基本字段,这很好,所以我们将继续。
要成为一个严格的弱排序,您应该只在基子对象相等(即两者都不小于另一个(时比较派生字段。
对于您当前的代码,如果您有lhs.mIntVal < rhs.mIntVal
,则应该返回true,但您继续比较派生字段,并可能最终说lhs
小于rhs
,而不是,即使基类的结果表明是。
因此,为了使结果正确,你需要一些等效的东西:
bool operator<(const Derived& rhs) const {
if (Base::operator<(rhs))
return true;
else if (rhs.Base::operator<(*this))
return false;
// base parts are equivalent, compare derived parts:
return std::tie(mOtherStrVal, mOtherStrVal1) <
std::tie(rhs.mOtherStrVal, rhs.mOtherStrVal1);
}
这在逻辑上是正确的,但次优,因为您调用了Base::operator<
两次。如ecatmur所示,您可以通过在tie表达式中包含基础对象来避免这种情况。
相关文章:
- 为什么使用 "this" 指针调用派生成员函数?
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 在派生函数中指定void*参数
- 如何通过派生类函数更改基类中的向量
- 如何委托派生类使用其父构造函数?
- 如何使用单独文件中的派生类访问友元函数对象
- 派生类销毁的最佳实践是什么
- 如何使用基类指针引用派生类成员
- 派生类是否可以在抽象工厂设计模式中具有数据成员
- 使用基类指针创建对象时,缺少派生类析构函数
- 如何引用基类的派生类?
- 存储模板类型以强制转换回派生<T>
- 需要从 istream 和 ostream 派生 iostream
- 在 C++ 中用派生类型重写成员函数
- 具有多个类、派生类的C++正向声明
- 有没有一种"cleaner"的方法可以在指向基的指针向量中找到派生类的第一个实例?
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 如果基类包含双指针成员,则派生类的构造函数
- 为什么此派生对象无法访问基类的后递减方法?
- 有没有比在库中添加一个并非由所有派生类实现的新虚拟函数更好的设计实践