std::list Строгий слабый порядок
У меня много проблем с использованием функции 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 - это условие, когда в формуле присутствует углерод, поскольку система Хилла требует, чтобы, если в формуле присутствовал углерод, водород был следующим, в противном случае все в алфавитном порядке, включая водород, это продиктовано в другом разделе моего кода.
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 (украдено отсюда)
Или, если у вас нет 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
,