Other answers have already addressed the m_strSymbol == rhs.m_strSymbol
issue.
But, based on your description ("C" first, "H" next, everything else in order), it seems like you could want, if you have 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);
This is an easy way to write StrictWeakOrderings (stolen from here)
Or, if you don't have C++11 (or Boost pre-C++11), you can do something like this:
// 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;
I'm pretty sure I did that right, but as stated in the article posted above, doing it manually is prone to error and probably should be avoided...also, this could definitely be optimized further to reduce the number of string comparisons, at the risk of introducing bugs and obfuscating the code.
But it's unclear what m_bHasCarbon means and what effect that's supposed to have, so I'm not sure if this is what you need or not.