[英]C++ spaceship-operator and user-defined types: comparing a subset of attributes only
I have two classes.我有两节课。 The first one composing the second one.
第一个组成第二个。 Both classes have its own synthetized attribute that doesn't collaborate to either ordering or comparision.
这两个类都有自己的综合属性,不协作排序或比较。 In addition, I want to use
std::ranges::sort
over a container of the second one, so I need to implement a strong-ordering.另外,我想在第二个容器上使用
std::ranges::sort
,所以我需要实现强排序。 That's what I have:这就是我所拥有的:
struct basic
{
std::string synthetized; // string representation of the next field.
unsigned value;
unsigned property;
friend bool operator<(basic const& a, basic const& b)
{ return a.value < b.value or (a.value == b.value and a.property < b.property); }
};
struct composed
{
basic value;
custom_type meta;
friend bool operator<(composed const& a, composed const& b)
{ return a.value < b.value; }
};
int main()
{
std::vector<composed> container;
// populating container
// Compilation error here.
std::ranges::sort(container);
}
How should I appropiately efficiently overload operator<=>
?我应该如何适当有效地重载
operator<=>
? Although what I need is to sort the vector and that's it (I could just go to traditional std::sort
), I want to know how to give to both classes full relational capabilities (<, <=, ==, !=, etc) to both classes, but ignoring synthetized
and meta
, and without doing anything stupid performance-wise.虽然我需要对向量进行排序,仅此而已(我可以使用传统的
std::sort
),但我想知道如何为这两个类提供完整的关系能力(<、<=、==、!=、等)到这两个类,但忽略synthetized
和meta
,并且没有做任何愚蠢的表现。
How should I appropiately efficiently overload
operator<=>
?我应该如何适当有效地重载
operator<=>
?
The simplest way to do both would probably be to use std::tie
and use the existing function template for operator<=>
for tuple
types:最简单的方法可能是使用
std::tie
并将现有的函数模板用于operator<=>
用于tuple
类型:
template< class... TTypes, class... UTypes >
constexpr /* see link */ operator<=>( const std::tuple<TTypes...>& lhs,
const std::tuple<UTypes...>& rhs );
Example:例子:
#include <tuple>
struct basic {
std::string synthetized; // excluded from comparisons
unsigned value;
unsigned property;
friend auto operator<=>(basic const& a, basic const& b) {
return std::tie(a.value, a.property) <=> std::tie(b.value, b.property);
}
};
struct composed {
basic value;
custom_type meta; // excluded from comparisons
friend auto operator<=>(composed const& a, composed const& b) {
return a.value <=> b.value;
}
};
You should also add operator==
which will also be used for !=
so you don't have to overload operator!=
.您还应该添加
operator==
这也将用于!=
因此您不必重载operator!=
。
I want to know how to give to both classes full relational capabilities (<, <=, ==, !=, etc) to both classes, but ignoring synthetized and meta, and without doing anything stupid performance-wise.
我想知道如何为这两个类赋予两个类完整的关系能力(<、<=、==、!= 等),但忽略综合和元,并且不做任何愚蠢的性能方面的事情。
Define comparison member functions for your type为您的类型定义比较成员函数
#include <string>
struct basic
{
std::string synthetized; // string representation of the next field.
unsigned value;
unsigned property;
constexpr auto operator<=>(const basic& other) const noexcept {
if (auto c = value <=> other.value; c != 0)
return c;
return property <=> other.property;
}
constexpr bool operator==(const basic& other) const noexcept {
return value == other.value && property == other.property;
}
};
struct composed
{
basic value;
custom_type meta;
constexpr auto operator<=>(const composed& other) const noexcept {
return value <=> other.value;
}
constexpr bool operator==(const composed& other) const noexcept {
return value == other.value;
}
};
Note that in your example operator<=>
does not synthesize operator==
because it is not the default, so you still need to define operator==
for your type to satisfy total_ordered_with
.请注意,在您的示例中
operator<=>
不会合成operator==
因为它不是默认值,因此您仍然需要为您的类型定义operator==
以满足total_ordered_with
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.