I want to make unique and order in set<Foo, FooComp>
.
In below code, I want a to unique and order by b and c. So, no same foo.a
and order by foo.b
and foo.c
.
How can I do this?
struct Foo {
int a, b, c;
Foo(int a, int b, int c) : a(a), b(b), c(c) {}
}
struct FooComp {
bool operator() (const Foo& f, const Foo& s) const {
if (f.pattern == s.pattern) {
return false;
}
if (f.start == s.start) {
return f.length < s.length;
}
return f.start < s.start;
}
}
or am I use other STL or data structures?
This is not possible using the standard library set.
The comparison operator is tightly coupled with the ordering.
Although a bit worse solution in terms of performance, you could have a set that contains all your objects, sorted by 'a' only using:
struct Foo {
int a, b, c;
Foo(int a, int b, int c) : a(a), b(b), c(c) {}
bool operator<(const Foo& rhs) const {
return a < rhs.a;
}
friend ostream& operator<<(ostream&, const Foo&);
};
And then, whenever you want to sort it using your unique algorithm, just copy it into a vector and sort it according to your needs:
vector<Foo> v;
std::copy(s.begin(), s.end(), std::back_inserter(v));
std::sort(v.begin(), v.end(), [](const Foo& lhs, const Foo& rhs){ return (lhs.b == rhs.b) ? lhs.c > rhs.c : lhs.b > rhs.b; });
Edited
This implements the logic you used in your Pastebin example. Entire sample here
There's a ready-made library for this kind of thing in boost called boost.multi_index.
It allows the declaration of a container that satisfies multiple indexes and their constraints.
It's a little archaic and could do with some love but it does the job.
You can start with something like this:
struct Foo {
int a, b, c;
Foo(int a, int b, int c) : a(a), b(b), c(c) {}
};
#include <tuple>
#include <type_traits>
#include <utility>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
struct get_a
{
using result_type = int const&;
result_type operator()(Foo const& l) const {
return l.a;
}
};
struct get_bc
{
using result_type = std::tuple<int const&, int const&>;
result_type operator()(Foo const& l) const {
return std::tie(l.b, l.c);
}
};
namespace foo {
using namespace boost;
using namespace boost::multi_index;
struct by_a {};
struct by_bc {};
using FooContainer =
multi_index_container
<
Foo,
indexed_by
<
ordered_unique<tag<by_a>, get_a>,
ordered_non_unique<tag<by_bc>, get_bc>
>
>;
}
int main()
{
foo::FooContainer foos;
foos.insert(Foo{ 1, 2,3 });
foos.insert(Foo{ 2, 2,4 });
}
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.