简体   繁体   English

C++ spaceship-operator 和用户定义类型:仅比较属性的子集

[英]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 ),但我想知道如何为这两个类提供完整的关系能力(<、<=、==、!=、等)到这两个类,但忽略synthetizedmeta ,并且没有做任何愚蠢的表现。

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

Demo演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM