У меня много проблем с использованием функции std :: list :: sort, она работает большую часть времени, однако время от времени выбрасывает утверждение «неверный оператор»<». Рассматривая эту проблему, я понял, что это потому, что моя функция сортировки не следует строгому слабому упорядочению, однако, когда я смотрю на свой код, я не понимаю, почему он не следует строгому слабому упорядочению, поскольку кажется правильным, что я пропускаю Вот?
Назначение этой функции — отсортировать список элементов в строку формулы на основе системы Hill, т.е. Первый углерод, второй водород, все остальные по алфавиту. 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 — это условие, когда в формуле присутствует углерод, поскольку система Хилла требует, чтобы, если в формуле присутствовал углерод, водород был следующим, в противном случае все в алфавитном порядке, включая водород, это продиктовано в другом разделе моего кода.
Другие ответы уже адресованы m_strSymbol == rhs.m_strSymbol
вопрос.
Но, исходя из вашего описания (сначала «С», затем «Н», все остальное в порядке), кажется, что вы мог хочу, если у вас есть 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 (украден из Вот)
Или, если у вас нет 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 означает, и какой эффект это должно иметь, так что я не уверен, что это то, что вам нужно или нет.
//If the symbols are equal
if(m_strSymbol == rhs.m_strSymbol)
return true;
Это означает, что это верно для обоих a<b
а также b<a
если символы равны
Возможно, вам следует return false
, поскольку a==b
и поэтому !a<b
, в этом случае.
Также ваш второй набор сравнений сбивает с толку .. что m_bHasCarbon
,