This is what I have:
struct Foo {
int index;
}
std::set<std::shared_ptr<Foo>> bar;
I want to order bar
's elements by their indices instead of by the default std::less<std::shared_ptr<T>>
function, which relates the pointers.
I read I can type
std::set<std::shared_ptr<Foo>, std::owner_less<std::shared_ptr<Foo>>> bar
, but I'd prefer to stick to the previous syntax.
I tried defining std::less<std::shared_ptr<Foo>>
, but it's not actually being used by the set
functions. Is there a way I can achieve this?
If you want to compare by their indices, you'll have to write a comparator that checks by their indices. std::less<>
will do the wrong thing (since it won't know about index
) and std::owner_less<>
will do the wrong thing (since it still won't compare the Foo
s, but rather has to do with ownership semantics of them).
You have to write:
struct SharedFooComparator {
bool operator()(const std::shared_ptr<Foo>& lhs,
const std::shared_ptr<Foo>& rhs) const
{
return lhs->index < rhs->index;
}
};
and use it:
std::set<std::shared_ptr<Foo>, SharedFooComparator> bar;
You could additionally generalize this to a generic comparator for shared_ptr's:
struct SharedComparator {
template <typename T>
bool operator()(const std::shared_ptr<T>& lhs,
const std::shared_ptr<T>& rhs) const
{
return (*lhs) < (*rhs);
}
};
and then simply make Foo
comparable.
You can provide your own specialization of less<shared_ptr<Foo>>
in the std
namespace.
namespace std
{
template<>
class less<shared_ptr<Foo>>
{
public:
bool operator()(const shared_ptr<Event>& a, const shared_ptr<Event>& b)
{
// Compare *a and *b in some way
}
};
}
Then you can form a set<shared_ptr<Foo>>
without a comparator. I needed this for a priority_queue<shared_ptr<Foo>>
, where I didn't want to use a priority_queue<Foo*, vector<Foo*>, int (*)(const Foo*, const Foo*)>
. I am not proud of it, but it works.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.