boost :: multi_index_container, operaciones en std :: set inside container
He creado un impulso :: multi_index_container (containerSet
) sobre una clase de contenedor e indexado elcontainerSet
porstd::string
ystd::set<int>
. ¿Es posible obtener el contenedor, que almacena un int específico dentro de su conjunto? Además, ¿es posible obtener todos los contenedores, que almacenan al menos un valor entre int1 e int2 dentro de su conjunto?
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/format.hpp>
#include <boost/lambda/core.hpp>
#include <iostream>
using boost::multi_index_container;
using namespace boost::multi_index;
class Container {
public:
std::set<int> set;
std::string name;
Container(std::string name, std::set<int> set);
~Container();
friend std::ostream& operator<<(std::ostream& os,const Container& c) {
os << c.name << ", [ ";
for (int i : c.set) {
os << i << " ";
}
os << "]";
return os;
}
};
Container::Container(std::string name = "noName", std::set<int> set = {}) : name{name} ,set{set} {}
Container::~Container() {}
struct setTag{};
struct nameTag{};
typedef multi_index_container<Container, indexed_by<
ordered_unique<tag<nameTag>, BOOST_MULTI_INDEX_MEMBER(Comp, std::string, name)>,
ordered_unique<tag<setTag>, BOOST_MULTI_INDEX_MEMBER(Comp, std::set<int>, set)>
>> ContainerSet;
//don't see how I could get the compare structs to work, because
//a) can't fullfill the strict weak odering requirements and
//b) because of the setTag ordering, not all set's get called
struct compSetRange {
bool operator()(int x,const std::set<int> &c) const {}
bool operator()(const std::set<int> &c, int x) const {}
};
struct compSetFind {
bool operator()(int x,const std::set<int> &c) const {}
bool operator()(const std::set<int> &c, int x) const {}
};
int main() {
Container c1{"c1", {5, 6, 7, 18, 61, 77}};
Container c2{"c2", {2, 4, 5, 21, 36, 88, 99}};
Container c3{"c3", {2, 3, 9, 10, 65, 75, 91}};
ContainerSet cs;
cs.insert(c1);
cs.insert(c2);
cs.insert(c3);
std::cout << "print by name (ordered)" << std::endl;
for (auto e : cs.get<nameTag>()) {
std::cout << e << std::endl;
}
std::cout << std::endl;
std::cout << "print by set (ordered)" << std::endl;
for (auto e : cs.get<setTag>()) {
std::cout << e << std::endl;
}
std::cout << std::endl;
typedef ContainerSet::index<setTag>::type compBySetIndex;
//find(std::set) works but isn't useful in my case
compBySetIndex::iterator it1 = cs.get<setTag>().find(std::set<int>{2, 4, 5, 21, 36, 88, 99});
//TODO: find all comps with int 5 -> c1 and c2
// compBySetIndex::iterator it1 = cs.get<setTag>().find(200, compSetFind());
if (it1 !=cs.get<setTag>().end()) {
std::cout << *it1 << std::endl;
}
//TODO: find all container with values between 70 and 80 -> c1 and c3
// compBySetIndex::iterator it1_low = cs.get<setTag>().lower_bound(70, compSetRange());
// compBySetIndex::iterator it1_upp = cs.get<setTag>().upper_bound(80, compSetRange());
//.range() also not applicable
return 0;
}
Con los conjuntos:c3 = {2, 3, 9, 10, 65, 75, 91}
c2 = {2, 4, 5, 21, 36, 88, 99}
c1 = {5, 6, 7, 18, 61, 77}
Quiero poder llamar...find(5);
y obtener al menosc2
, tal vez inclusoc1
en la próxima invocación. Esto podría ser factible con la función de comparación correcta, pero no se me ocurre una manera de hacer que las funciones operator ()compatible.
Además después...lower_bounds(70)
y...upper_bounds(80)
Debería conseguirc3
yc1
. Debido al orden de std :: set's, este requisito parece inalcanzable con boost.
¿Me estoy perdiendo de algo? ¡Gracias por adelantado!
Sé que podría hacer una búsqueda lineal en todos los contenedores y sus conjuntos para lograr mi objetivo, pero eso negaría la ventaja de rendimiento del multi_index_container. Si el impulso es la herramienta incorrecta para este trabajo, tendré que recurrir a un individuoclass containerSet
.