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)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With