¿Por qué boost-multi-index devuelve un iterador incorrecto?
Frecuentes
Visto 743 veces
0
Los documentos de Boost decían que iterator_to devuelve un iterador válido, pero el siguiente código muestra que sucede algo diferente.
Todos los índices de Boost.MultiIndex proporcionan una función miembro llamada iterator_to que devuelve un iterador a un elemento dado del contenedor.
http://www.boost.org/doc/libs/1_51_0/libs/multi_index/doc/tutorial/indices.html#iterator_to
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/random_access_index.hpp>
using boost::multi_index_container;
using namespace boost::multi_index;
struct Test
{
int id;
std::string name;
};
struct idx{};
struct id{};
struct name{};
typedef boost::multi_index_container<
Test*,
indexed_by<
random_access<tag<idx> >,
ordered_unique<tag<id>, member<Test, int, &Test::id> >,
ordered_unique<tag<name>, member<Test, std::string, &Test::name> >
>
> TTestTable;
class TestTable : public TTestTable
{
public:
// Fill table with some values
TestTable()
{
Test* test1 = new Test();
Test* test2 = new Test();
Test* test3 = new Test();
Test* test4 = new Test();
test1->id = 1;
test2->id = 2;
test3->id = 3;
test4->id = 4;
test1->name = "name1";
test2->name = "name2";
test3->name = "name3";
test4->name = "name4";
push_back(test1);
push_back(test2);
push_back(test3);
std::cout << at(0)->name << std::endl;
std::cout << at(1)->name << std::endl;
std::cout << at(2)->name << std::endl;
typedef TTestTable::index<idx>::type test_table_by_index;
test_table_by_index::iterator it = get<0>().iterator_to(test1); // gives back a wrong iterator
std::cout << get<idx>().iterator_to(test1) - get<idx>().begin() << "\n"; // WRONG
replace(iterator_to(test1), test4); // CRASH
replace(it, rule4); // CRASH
}
};
int
main(int argc, char **argv)
{
TestTable table;
return 0;
}
1 Respuestas
3
Desde el enlace que proporcionó:
// The following, though similar to the previous code,
// does not work: iterator_to accepts a reference to
// the element in the container, not a copy.
int x=c.back();
c.erase(c.iterator_to(x)); // run-time failure ensues
No estás pasando una referencia a iterator_to
, estás pasando una copia.
Lo siguiente debería funcionar:
Test* const& test1_ref = at(0);
typedef TTestTable::index<idx>::type test_table_by_index;
test_table_by_index::iterator it = get<0>().iterator_to(test1_ref);
std::cout << get<idx>().iterator_to(test1_ref) - get<idx>().begin() << "\n";
replace(iterator_to(test1_ref), test4);
Aparte, no creo boost::multi_index_container
s están diseñados para ser utilizados como clases base ya que no proporcione un destructor virtual.
Respondido 26 ago 12, 02:08
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas c++ boost boost-multi-index or haz tu propia pregunta.
Realmente deberías usar la composición.
multi_index
tiene tantas características que los usuarios de su clase nunca deberían conocer y esto lo oculta mucho mejor (además de lavirtual
problema de dtor). - pmr