0

Boostのドキュメントによると、iterator_toは有効なイテレータを返しますが、以下のコードは他のことが起こっていることを示しています。

Boost.MultiIndexのすべてのインデックスは、コンテナの特定の要素にイテレータを返すiterator_toというメンバー関数を提供します。

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;
}
4

1 に答える 1

3

あなたが提供したリンクから:

// 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

に参照を渡すのではなくiterator_to、コピーを渡します。

以下が機能するはずです。

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);

余談ですが、 sは仮想デストラクタを提供しないため、boost::multi_index_container基本クラスとして使用するように設計されているとは思いません。

于 2012-08-26T01:02:38.510 に答える