提问人:ABu 提问时间:7/9/2022 更新时间:7/9/2022 访问量:1744
C++ 宇宙飞船运算符和用户定义类型:仅比较属性的子集
C++ spaceship-operator and user-defined types: comparing a subset of attributes only
问:
我有两个班级。第一个组成第二个。这两个类都有自己的合成属性,该属性不与排序或比较协作。此外,我想在第二个容器上使用,所以我需要实现强排序。这就是我所拥有的:std::ranges::sort
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);
}
我应该如何适当有效地超载?虽然我需要的是对向量进行排序,仅此而已(我可以去传统),我想知道如何为两个类提供完整的关系功能(<、<=、==、!= 等)给两个类,但忽略 和 ,并且不做任何愚蠢的性能方面的事情。operator<=>
std::sort
synthetized
meta
答:
4赞
Ted Lyngmo
7/9/2022
#1
我应该如何适当有效地超载?
operator<=>
实现这两者的最简单方法可能是使用 std
::tie 并使用 operator<=>
的现有函数模板来表示类型:tuple
template< class... TTypes, class... UTypes >
constexpr /* see link */ operator<=>( const std::tuple<TTypes...>& lhs,
const std::tuple<UTypes...>& rhs );
例:
#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;
}
};
您还应该添加 which 也将用于 这样您就不必重载了 .operator==
!=
operator!=
2赞
康桓瑋
7/9/2022
#2
我想知道如何给两个类提供完整的关系 功能(<、<=、==、!= 等)添加到两个类,但忽略 合成和元,不做任何愚蠢的事情 性能方面。
为您的类型定义比较成员函数
#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;
}
};
请注意,在您的示例中不会进行合成,因为它不是默认值,因此您仍然需要定义您的类型以满足total_ordered_with
。operator<=>
operator==
operator==
评论
0赞
Goswin von Brederlow
7/9/2022
您可以默认 or,它将用于所有内容。operator==
operator!=
<=>
1赞
Goswin von Brederlow
7/9/2022
怎么样 ?struct composed : basic { custom_type meta; using basic::operator<=>; using basic::operator==;};
1赞
Barry
7/10/2022
@Goswin Defaulting 不会使用 ,它将生成成员平等。==
<=>
0赞
Goswin von Brederlow
7/10/2022
@Barry该死的,我看错了。关于默认operator@将使其使用的部分仅适用于 。<=>
< > <= >=
上一个:运算符重载复制构造和 = 运算符
评论
operator<
meta
operator<=>
this
operator<
composed
3 < x
<