Herb Sutter, в своем предложении для оператора "космического корабля" (раздел 2.2.2, внизу страницы 12), говорит:
Основываясь на
<=>
и его возвращаемом типе:. Эта модель имеет основные преимущества, некоторые из которых уникальны для этого предложения по сравнению с предыдущими предложениями для С++ и возможностями других языков:[...]
(6) Эффективность, в том числе, наконец, достижение абстракции с нулевой накладкой для сравнений: Подавляющее большинство сравнений всегда однопроходное. Единственное исключение генерируется
<=
и>=
в случае типов, которые поддерживают как частичное упорядочение, так и равенство. Для<
однократный проход необходим для достижения принципа "нулевой накладной", чтобы избежать повторения сравнений равенства, например, дляstruct Employee { string name; /*more members*/ };
, используемого вstruct Outer { Employeee; /*more members*/ };
- сегодняшние сравнения нарушают абстракцию с нулевым накладным капиталом, потому чтоoperator<
наOuter
выполняет избыточные сравнения сравнений, поскольку выполняетif (e != that.e) return e < that.e;
, который пересекает равный префиксe.name
в два раза (и если имя равно, одновременно проходит равные префиксы других членовEmployee
), и это вообще невозможно оптимизировать. Как отмечает Каминьски, абстракция с нулевым потоком является столпом С++, и достижение ее для сравнений в первый раз является значительным преимуществом этого дизайна на основе<=>
.
Но затем он приводит этот пример (раздел 1.4.5, стр. 6):
class PersonInFamilyTree { // ...
public:
std::partial_ordering operator<=>(const PersonInFamilyTree& that) const {
if (this->is_the_same_person_as ( that)) return partial_ordering::equivalent;
if (this->is_transitive_child_of( that)) return partial_ordering::less;
if (that. is_transitive_child_of(*this)) return partial_ordering::greater;
return partial_ordering::unordered;
}
// ... other functions, but no other comparisons ...
};
Определял бы operator>(a,b)
как a<=>b > 0
не приводить к большим накладным расходам? (хотя в другой форме, чем он говорит). Этот код будет сначала проверять на равенство, затем на less
и, наконец, на greater
, а не только и непосредственно тестировать для greater
.
Я что-то пропустил?