On the other hand, it is not clear that you are allowed to add operators
for standard types. Usually the requirement is that at least one
parameter is of a user-defined type.


In this case the custom overload of operator== is in the global namespace, so while perhaps unwise, this is not illegal.

Perhaps better to reimplement reference_wrapper in a new namespace leveraging what's available in the standard library?

https://godbolt.org/z/a85c9jPG4


#include <functional>
#include <iostream>


namespace my_program
{
    template<class X>
    struct reference_wrapper : std::reference_wrapper<X>
    {
        using std::reference_wrapper<X>::reference_wrapper;
    };

    template<class X, class Y>
    bool operator==(reference_wrapper<X> const& x, reference_wrapper<Y> const& y)
    {
        return x.get() == y.get();
    }

    template<class T>
    reference_wrapper<T const>
    cref(T const& x)
    {
        return reference_wrapper<const T>(x);
    }

    template<class T>
    reference_wrapper<T>
    ref(T & x)
    {
        return reference_wrapper<T>(x);
    }
}

namespace some_lib
{
    struct C
    {
        int val;
    };

    bool operator==(C const& a, C const& b) {
        return a.val == b.val;
    }
}

int main()
{
    auto a = some_lib::C { 100 };
    auto b = some_lib::C { 101 };

    auto ra = my_program::cref(a);
    auto rb = my_program::ref(b);

    std::cout << std::boolalpha << (a == b) << std::endl;
    std::cout << (ra == b) << std::endl;
    std::cout << (a == rb) << std::endl;
    std::cout << (ra == rb) << std::endl;
    std::cout << (a == a) << std::endl;
    std::cout << (ra == a) << std::endl;
    std::cout << (a == ra) << std::endl;
    std::cout << (ra == ra) << std::endl;
}

 

--
Std-Discussion mailing list
Std-Discussion@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion