7

I would like to compare two objects through their addresses. I tried operator overloading and it does not seem to work for pointers, but works for objects themselves. The following is the relevant code:

class C {
        public:
                int x;
};
.
.
.
bool operator <( C *ptr_c1, C *ptr_c2 )
{
        return ( (*ptr_c1).x < (*ptr_c2).x );
}
  • @snjv: Are you saying that, given pointers to `C` you want to compare them, but for the comparison to be based on some member, such as `x`? – quamrana Sep 14 '09 at 07:18
  • yes, that is exactly require! –  Sep 14 '09 at 07:29
  • See these: * [Universal `less<>` for pointers in C++ standard](https://stackoverflow.com/questions/1098966/universal-less-for-pointers-in-c-standard) * [What are the operations supported by raw pointer and function pointer in C/C++?](https://stackoverflow.com/questions/1418068/what-are-the-operations-supported-by-raw-pointer-and-function-pointer-in-c-c) – Daniel Daranas Sep 14 '09 at 06:44

3 Answers3

11

I tried operator overloading and it does not seem to work for pointers,

Correct.

but works for objects themselves.

Correct.

So what is the question?

Do you want to use pointers in a sorted container?

With:

#include <iostream>
#include <set>

struct X
{
    int x;
};

C++ 11 and later

int main()
{
    X       x1; x1.x    = 5;
    X       x2; x2.x    = 6;

    auto compare = [](auto const& lhs, auto const& rhs){return lhs->x < rhs->x;};
    std::set<X*, decltype(compare)> plop(compare);

    plop.insert(&x1);
    plop.insert(&x2);
}

In C++ 03

struct XPTest
{
    bool operator()(X* const& lhs,X* const& rhs)
    {
        return lhs->x < rhs->x;
    }
};

int main()
{
    X       x1; x1.x    = 5;
    X       x2; x2.x    = 6;

    std::set<X*,XPTest> plop;

    plop.insert(&x1);
    plop.insert(&x2);
}
Martin York
  • 257,169
  • 86
  • 333
  • 562
  • Why do we have to use a new struct ? Cant we use the struct X ? – Ediolot Oct 17 '15 at 20:59
  • 1
    @Ediolot: You could. But that would be a bad idea. The second class passed to `std::set` is supposed to be a comparison class. Putting the test in `X` and then declaring `std::set` does not seem very logical. – Martin York Oct 18 '15 at 21:01
  • Can the same be achieved by overloading `operator<` for `X` itself? – CinCout Mar 20 '19 at 06:01
5

A pointer is a native C++ type and you can only overload operators for user defined types (i.e. classes).

If this was possible it would violate the principal of 'least surprise' and cause pointer comparisons to behave differently based on whether not your definition was visible. This would probably be very confusing.

If you want to use an alternative comparison for use in container or with algorithms, note that you can provide a replacement for the default std::less in most associative containers and algorithms that require a partial order.

CB Bailey
  • 755,051
  • 104
  • 632
  • 656
  • Why is the change of behavior less "surprising" when you use template specialization of `std::less`? – mastov May 25 '16 at 14:54
  • @mastov: It's not legal to specialize `std::less` for raw pointers. Using another function object to _replace_ `std::less` should be less surprising because it needs to be explicitly specified. – CB Bailey May 25 '16 at 21:41
  • Sure, something replacing `std::less` that is *not* a specialization would be less surprising (since it has to be used explicitly), I misread your answer there, I understood that you wanted to *specialize* `std::less`. Anyway, I couldn't find a reference for specialization of `std::less` for raw pointers being illegal. Who/what says it is? – mastov May 26 '16 at 10:23
1
if(*obj1 < *obj2) { /* this should use the overloaded operator. */ }
KiNgMaR
  • 1,557
  • 10
  • 16