0

What is this header for?

It defines, just to give an example, equal_to:

namespace ranges
{
    /// \addtogroup group-functional
    /// @{
    struct equal_to
    {
        template(typename T, typename U)(
            /// \pre
            requires equality_comparable_with<T, U>)
        constexpr bool operator()(T && t, U && u) const
        {
            return (T &&) t == (U &&) u;
        }
        using is_transparent = void;
    };

    // ... and the others, such as !=, <, <=, ...
}

But what is the advantage of ranges::equal_to over std::equal_to? Only saving <> when instantiating an object of it's class, i.e. writing ranges::equal_to{} instead of std::equal_to<>{}?

Enlico
  • 23,259
  • 6
  • 48
  • 102
  • 1
    I think this is compatibility related. Range v3 first was written using C++14 (AFAIR). Now since C++20 is used (I see feature `requires`), this remained to not break existing code which used this struct before C++20 was introduced to a code base. – Marek R Jan 10 '23 at 10:24
  • BTW, you don't need the `<>` with std::equal_to either anymore. This is a language version thing, and not a library thing. – BoP Jan 10 '23 at 10:37
  • @BoP, why not a library thing? Isn't it simply that they added a `void` specialization for the template class? (I'm referring to `template< class T = void > struct equal_to;` at [cppreference](https://en.cppreference.com/w/cpp/utility/functional/equal_to).) – Enlico Jan 10 '23 at 10:52
  • 1
    @Enlico omitting the empty `<>` is a language feature of C++17 – Caleth Jan 10 '23 at 14:01
  • 1
    It has the same advantages over `std::equal_to` that `std::ranges::equal_to` has. I suppose a better question would have been why C++20 added `std::ranges::equal_to`, which would have been easily researched – ildjarn Jan 11 '23 at 17:53

1 Answers1

1

What is the advantage of ranges::equal_to over std::equal_to? Only saving <> when instantiating an object of its class, i.e. writing ranges::equal_to{} instead of std::equal_to<>{}?

That is not true, since omitting empty <> has been allowed since C++17.


What is range/[...]/comparisons.hpp for?

The main differences between the ranges:: comparison function objects and the base versions is that the ranges versions are much more constrained, due to the requirement equality_comparable_with<T, U>. The same difference also applies between and std:: version and C++20 std::ranges:: version.


For std::equal_to{}(a, b) to be valid code, all you need is a == b being valid code.

However, for ranges::equal_to{}(a, b) to be valid code, a and b must satisfy the equality_comparable requirement. Which means not only a == b need to be valid, all equality checks between a and b must also be valid code(includes self comparison), which would include:

a == a;
a != a;
b == b;
b != b;
a == b;
a != b;
b == a;
b != a;

In the same time, there must also be a common type C between a and b, where both c == c and c != c are valid code.


Similar behaviors can be observed on other ranges:: comparison function objects, such as ranges::not_equal_to and ranges::less.

Ranoiaetep
  • 5,872
  • 1
  • 14
  • 39