Это связано с недостатком конструкции того, как C ++ в настоящее время обрабатывает сравнение. Они исправляют это в c ++ 2a ; Я не знаю, дойдет ли он до vector
, но фундаментальная проблема будет исправлена.
Во-первых, проблема.
std::vector
<
основано на каждом элементе <
. Но <
плохой инструмент для этой работы.
Если у вас есть два элемента a
и b
, чтобы лексографически упорядочить кортеж a,b
, вам нужно сделать:
if (self.a < other.a)
return true;
if (other.a < self.a)
return false;
return self.b < other.b;
В общем, для этого требуется 2N-1 вызовов <
, если вы хотите лексографически упорядочить коллекцию из N элементов.
Это известно давно, и поэтому strcmp
возвращает целое число с 3 видами значений: -1
для меньшего, 0
для равного и +1
для большего (или, в общем, значение меньше, равно или больше нуля).
С этим вы можете сделать:
auto val = compare( self.a, other.a );
if (val != 0) return val;
return compare( self.b, other.b );
для этого требуется до N
вызовов до compare
на элемент в коллекции.
Теперь исправление.
c ++ 2a добавляет оператор сравнения космического корабля <=>
. Он возвращает тип, который можно сравнить больше или меньше нуля, и точный тип которого объявляет, что гарантирует операция.
Это действует как C strcmp
, но работает с любым типом, который его поддерживает. Кроме того, существуют std
функции, которые используют <=>
, если они доступны, и в противном случае используют <
и ==
и т.п. для эмуляции.
При условии, что требования вектора переписаны для использования <=>
, типы с <=>
позволят избежать двойного сравнения и просто будут <=>
'd не более одного раза каждый, чтобы выполнить лексографическое упорядочение std::vector
при <
называется.