Movatterモバイル変換


[0]ホーム

URL:


Group Actions
Engagement
  • AuthorAuthor:Jan Cumps
  • Date Created:Date Created
  • Views189 views
  • Likes7 likes
  • Comments5 comments
Related
Recommended

C++ 3 way compare

task: Let's say that you are writing a C++ class, where the objects have to be sorted or compared.

In classic C++, you 'd write an operator overload for<,<=== ,!=, >= and>. In modern C++, you can get all that functionality with a single method:<=> (aka the spaceship operator).
If you provide an implementation for that operator, the compiler will derive all comparisons.

class compare_me { public:    constexpr compare_me(int value): value{value} { }    auto operator<=>(const compare_me& rhs) const = default;   private:    int value;};

I'm using C++ default<=> implementation here. It will compare all the class data members - if they support comparison. In this example, the operator will compare thevalue data member.
If you can't (or don't want to) use that functionality, you can provide your own implementation. For the rules on how default works, seeDefault comparisons order.

This is functionality you get when providing this single operator overload in your class:

    constexpr compare_me value_1(1);    constexpr compare_me value_2(2);    constexpr compare_me other_value_2(2);    constexpr compare_me value_3(3);        std::cout << (value_1 < value_1) << std::endl;    std::cout << (value_1 < value_2) << std::endl;    std::cout << (value_2 < other_value_2) << std::endl;    std::cout << (value_2 <= other_value_2) << std::endl;    std::cout << (value_2 >= other_value_2) << std::endl;    std::cout << (value_2 == other_value_2) << std::endl;    std::cout << (value_2 != other_value_2) << std::endl;    std::cout << (value_2 <= other_value_2) << std::endl;    std::cout << (value_3 < value_2) << std::endl;    std::cout << (value_3 <= value_2) << std::endl;    std::cout << (value_3 > value_2) << std::endl;    std::cout << (value_3 >= value_2) << std::endl;

Result:

false
true
false
true
true
true
false
true
false
false
true
true

Complete code:

#include <compare>#include <iostream>class compare_me { public:    constexpr compare_me(int value): value{value} { }    auto operator<=>(const compare_me& rhs) const = default;   private:    int value;};int main() {      constexpr compare_me value_1(1);    constexpr compare_me value_2(2);    constexpr compare_me other_value_2(2);    constexpr compare_me value_3(3);    std::cout << std::boolalpha << std::endl;        std::cout << (value_1 < value_1) << std::endl;    std::cout << (value_1 < value_2) << std::endl;    std::cout << (value_2 < other_value_2) << std::endl;    std::cout << (value_2 <= other_value_2) << std::endl;    std::cout << (value_2 >= other_value_2) << std::endl;    std::cout << (value_2 == other_value_2) << std::endl;    std::cout << (value_2 != other_value_2) << std::endl;    std::cout << (value_2 <= other_value_2) << std::endl;    std::cout << (value_3 < value_2) << std::endl;    std::cout << (value_3 <= value_2) << std::endl;    std::cout << (value_3 > value_2) << std::endl;    std::cout << (value_3 >= value_2) << std::endl;                  std::cout << std::endl;              }

Bonus: use STL sorting algorithm on a container of our objects

Example: execute a few STL algorithms on an an array of (initially) unsorted objects 

#include <array>#include <algorithm>    std::array<compare_me, 4> sort_me {2, 3, 2, 1};    for(const auto& cm : sort_me) { std::cout << cm << " "; }    std::cout << std::endl;    std::cout << "sorted? "<< std::is_sorted(sort_me.begin(), sort_me.end()) << std::endl;    std::sort(sort_me.begin(), sort_me.end());    for(const auto& cm : sort_me) { std::cout << cm << " "; }    std::cout << std::endl;    std::cout << "sorted? " << std::is_sorted(sort_me.begin(), sort_me.end()) << std::endl;

Output:

2 3 2 1
sorted? false
1 2 2 3
sorted? true

sorting algorithms used:

std::is_sorted()
std::sort()

By default, STL uses the< operator to sort. If you want to sort using other criteria, that's possible.
This snippet sorts the container from large to small:

std::sort(sort_me.begin(), sort_me.end(), [](const compare_me& a, const compare_me& b) {    return a > b;});for (const auto& cm : sort_me) { std::cout << cm << " "; }std::cout << std::endl;std::cout << "sorted? " << std::is_sorted(sort_me.begin(), sort_me.end(), [](const compare_me& a, const compare_me& b) {    return a > b;}) << std::endl;

3 2 2 1 
sorted? true

Bonus 2: print a container of our objects

To support printing, I also provided an<< operator for my classcompare_me:

   friendstd::ostream&operator<< (std::ostream&os,constcompare_me&cm) {
       returnos<<cm.value;
    }

You can then print an individual object to a stream (in this case: the standard output stream. 
To print the full array of objects, you can use this:

    for(const auto& cm : sort_me) { std::cout << cm << " "; }

Inspiration:MC++ 

attached: full code main.zip

Thank you for reading.


[8]ページ先頭

©2009-2025 Movatter.jp