Ваш оператор сравнения не прав. Пока вы можете предполагать, что никакие нули не добавлены, вы можете бросить, если обнаружите:
bool operator()(const string* s1, const string* s2) const
{
if (!s1 || !s2) throw std::runtime_error("Whatever");
return *s1 < *s2;
}
РЕДАКТИРОВАТЬ: Я должен был бы более подробно остановиться на рассуждениях здесь. Операция сравнения, которую вы передаете в std::map
(или set
или sort
, например), должна удовлетворять строгому слабому порядку. Это в основном означает, что x OP x
равно false
, если x OP y
равно true
, тогда y OP x
равно false
, и что x OP y
, y OP z
подразумевает x OP z
(а также другие правила, касающиеся предметов это нельзя сравнивать).
Ваша функция не удовлетворяет этому несколькими способами: if (s1 == s2)
необходимо вернуть false. if ((s1==NULL) || (s2==NULL))
не может вернуть false, потому что это будет означать, что null < anything
и anything < null
. Вам придется разделить его и вернуть true для s1
null и false для s2
null. return (0 == s1->compare(s2->c_str()));
неверно, потому что это трехсторонний результат, а не <
отношение.
Поскольку вы указали, что пустые значения никогда не будут вставлены, простейшим решением, по-видимому, было бы генерировать исключение в этом случае (если любое из них было нулевым), а затем использовать встроенный оператор строки.
Учитывая все вышесказанное, я бы настоятельно рекомендовал НЕ хранить строки по указателю в контейнерах, если у вас нет фактических доказательств того, что это узкое место в производительности. Более простую конструкцию легче поддерживать и поддерживать правильной, что приводит к улучшению программ в долгосрочной перспективе.