std :: list Strict Weak Ordering

时间:2013-02-28 02:10:20

标签: c++ list stl strict-weak-ordering

我在使用std :: list :: sort函数时遇到了很多麻烦,它在大多数情况下都有效,但每隔一段时间就会抛出一个断言'无效的运算符<'。看看这个问题我已经意识到这是因为我的排序函数没有遵循严格的弱排序,但是当我查看我的代码时,我不明白为什么它不遵循严格的弱排序,因为它似乎是正确的,我错过了什么这里吗?

此功能的目的是根据山丘系统将元素列表排序为公式字符串,即。碳首先,氢气第二,所有其他按字母顺序排列。 FormulaStruct仅表示完整公式中的单个元素和金额。

struct FormulaStruct
{
    FormulaStruct(const std::string & strSymbol, int nNum, bool bHasCarbon)
        :
            m_strSymbol(strSymbol),
            m_nNum(nNum), m_bHasCarbon(bHasCarbon)
    {
    }

    bool operator < (const FormulaStruct & rhs)
    {
        //If the symbols are equal
        if(m_strSymbol == rhs.m_strSymbol)
            return true;

        if(m_bHasCarbon)
        {       
            if(m_strSymbol == "C")
                return true;        
            else        
            if(rhs.m_strSymbol == "H")
                return false;           
        }

        return m_strSymbol < rhs.m_strSymbol;
    }

    bool operator == (const FormulaStruct & rhs)
    {
        return m_strSymbol == rhs.m_strSymbol;
    }

    std::string m_strSymbol;
    int         m_nNum;
    bool        m_bHasCarbon;
};

list<FormulaStruct> FormulaList; //A list of FormulaStructs, assumed to be filled
FormulaList.sort();

修改 bHasCarbon是配方中有碳的条件,因为山体系要求如果配方中有碳,则接下来是氢,否则一切都是按字母顺序排列的,包括氢,这在我的代码的另一部分中有所规定。

2 个答案:

答案 0 :(得分:2)

其他答案已经解决了m_strSymbol == rhs.m_strSymbol问题。

但是,根据你的描述(首先是“C”,接下来是“H”,其他所有顺序),如果你有C ++ 11,那么你似乎可以想要:

return std::tie(m_strSymbol != "C", m_strSymbol != "H", m_strSymbol)
    < std::tie(rhs.m_strSymbol != "C", rhs.m_strSymbol != "H", rhs.m_strSymbol);

这是编写StrictWeakOrderings的简便方法(从here中窃取)

或者,如果您没有C ++ 11(或Boost pre-C ++ 11),您可以这样做:

// order of checks here is important, in case both are "C"
if(rhs.m_strSymbol == "C")
    return false;
if(m_strSymbol == "C")
    return true;
// neither symbol is "C"
if(rhs.m_strSymbol == "H")
    return false;
if(m_strSymbol == "H")
    return true;
// neither symbol is "C" or "H"
return m_strSymbol < rhs.m_strSymbol;

我很确定我做得对,但正如上面发布的文章所述,手动操作很容易出错并且可能应该避免......此外,这肯定可以进一步优化以减少数量字符串比较,冒着引入错误和混淆代码的风险。

但目前还不清楚 m_bHasCarbon 意味着什么以及它应该具有什么效果,所以我不确定这是否是你需要的。

答案 1 :(得分:1)

//If the symbols are equal
if(m_strSymbol == rhs.m_strSymbol)
        return true;

如果符号相等,则表示a<bb<a都是如此。

在这种情况下,也许您应该 return false ,因为a==b!a<b

另外,你的第二组比较令人困惑..什么是m_bHasCarbon