[英]C++ STL: Using derived virtual class as “Strict Weak Ordering” for std::sort()
[英]C++ strict weak ordering derived class
我试图在要放置在STL集合容器中的子类中实施严格的弱排序。 STL集使用operator <来以严格的弱顺序对其元素进行排序。 就我而言,我有一个类型层次结构,我不太确定如何为派生类型实现这一点。 为此,我整理了一个快速的现场演示,展示了我不确定的地方。 我正在使用易于使用的std :: tie 技术订购字段。 我不确定的领域是在派生字段上调用std :: tie比较之前,应如何调用超类的operator <。
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表达式中包含基础对象来避免这种情况。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.