Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to store pointers (or references) to objects in a std::set

Tags:

c++

stl

Are there any proper means in the C++11 STL to store object pointers in a std::set, and have them sorted properly by the object's operator < method?

There is, of course, the possibility of writing my own Compare type and passing that to the set as its second template argument, but I'd imagine that the STL would provide a much more convenient way.

A bit of googling revealed std::reference_wrapper, which in my opinion should allow code like this:

#include <functional>
#include <set>

struct T {
    int val;
    bool operator <(T& other) {
        return (this->val < other.val);
    }
};

int main() {
    std::set<std::reference_wrapper<T>> s;
    T a{5};
    s.insert(a);
}

But in fact, this causes a compiler error:

clang++ -std=c++11 -Wall -Wextra -pedantic test.cpp -o test
In file included from test.cpp:1:
In file included from /usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.8.2/../../../../include/c++/4.8.2/functional:49:
/usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.8.2/../../../../include/c++/4.8.2/bits/stl_function.h:235:20: error: invalid operands to binary expression ('const std::reference_wrapper<T>'
      and 'const std::reference_wrapper<T>')
      { return __x < __y; }
               ~~~ ^ ~~~

(the gcc error is similar, but a lot longer)

like image 925
mic_e Avatar asked Jan 31 '14 19:01

mic_e


1 Answers

You need to make your less-than operator a non-member, and give it const reference parameters:

struct T {
    int val;
};

bool operator <(const T& lhs, const T& rhs) {
    return (lhs.val < rhs.val);
}

This allows for implicit conversions on from std::reference_wrapper<T> to T on both LHS and RHS of the < operator, whereas the member version only allows for an implicit conversion on the RHS. Symmetry between LHS and RHS of binary operators is one of the classic arguments for implementing them as non-members.

like image 93
juanchopanza Avatar answered Oct 25 '22 23:10

juanchopanza