Search code examples
c++boostc++17comparator

Can C++20's 'operator==(const T&) = default' be mimiqued in C++17?


In C++ 20 we are able let the compiler automatically generate the implementation for operator== for us like this (and all the other default comparasions too, but I'm just interested in operator== here):

#include <compare>
struct Point {
  int x;
  int y;
  bool operator==(const Point&) const = default;
};

Is there a way to archieve the same (automatically generate operator==) but in C++17?

Since libraries are an okay solution I had a look at boost/operators. Would the following be the equivalent as the above?

#include <boost/operators.hpp>
struct Point : boost<equality_comparable<Point, Point>> {
  int x;
  int y;
  bool operator==(const Point&) const; // will this get auto-generated too and do the same as above?
};

Solution

  • Only for aggregates (a slightly widened set around POD (trivial+standard layout) types).

    Using PFR you can opt in using a macro:

    Boost.PFR adds the following out-of-the-box functionality for aggregate initializable structures:

    • comparison functions
    • heterogeneous comparators
    • hash
    • IO streaming
    • access to members by index
    • member type retrieval
    • methods for cooperation with std::tuple
    • methods to visit each field of the structure

    Example using BOOST_PFR_FUNCTIONS_FOR:

    Defines comparison and stream operators for T along with hash_value function.

    See Also : 'Three ways of getting operators' for other ways to define operators and more details.

    Live On Coliru

    struct Point { int x, y; };
    
    #include <boost/pfr.hpp>    
    BOOST_PFR_FUNCTIONS_FOR(Point)
    
    #include <iostream>
    #include <vector>
    #include <set>
    int main() {
        std::vector pv { Point{1,2}, {2,1}, {-3,4}, {1,4/2}, {-3,-4} };
    
        for(auto& p : pv) std::cout << p << " ";
        std::cout << "\n";
    
        std::set ps(begin(pv), end(pv));
    
        for(auto& p : ps) std::cout << p << " ";
        std::cout << "\n";
    }
    

    Prints

    {1, 2} {2, 1} {-3, 4} {1, 2} {-3, -4} 
    {-3, -4} {-3, 4} {1, 2} {2, 1} 
    

    Using strictly c++14 (specifying vector<Point> and set<Point> template arguments).