Opened 9 years ago

Closed 9 years ago

Last modified 9 years ago

#9293 closed Bugs (wontfix)

multi_index_container iterator needs base object size

Reported by: anonymous Owned by: Joaquín M López Muñoz
Milestone: To Be Determined Component: multi_index
Version: Boost 1.46.0 Severity: Problem
Keywords: multi_index_set Cc:

Description

The reason this is a bug is because I cannot define 2 classes A&B that will be stored in sequenced containers, and have A&B each hold an iterator to the other's container.

For example, this works:

struct A;
struct B {
  std::list<A>::iterator a_it;
};
struct A {
  std::list<B>::iterator b_it;
};

However, if I want to replace both lists with sequenced multi_index_containers, I can no longer compile it.

The problem is that the iterator to a multi_index_container somehow calls sizeof on the stored class, so the forward declaration is not enough to compile.

Attachments (1)

test.cpp (799 bytes ) - added by anonymous 9 years ago.
use case demonstration

Download all attachments as: .zip

Change History (5)

by anonymous, 9 years ago

Attachment: test.cpp added

use case demonstration

comment:1 by anonymous, 9 years ago

I don't have the latest boost installed. If you do, please compile the attached file and let me know if it works. For me, g++ -std=c++0x -c test.c fails, but it works with -D USE_LIST.

comment:2 by Joaquín M López Muñoz, 9 years ago

Resolution: wontfix
Status: newclosed
Type: BugsFeature Requests

Hi,

The reason your example fails to compile is that multi_index_container does not work on so-called incomplete types, i.e. it needs to know the size of the element type at instantiation time. This is not a bug per se, although the ability to work with incomplete types is of course a desireable one.

Unfortunately I don't expect adding this capability any time soon as it needs some heavy refactoring I don't have currently the time for. Maybe you can replace your code with

struct A;
struct B {
  const A* a_p;
};
struct A {
  const B* b_p;
};

and use iterator_to to retrieve an iterator from a pointer when needed:

http://www.boost.org/libs/multi_index/doc/tutorial/indices.html#iterator_to

Let me know if that works for you.

comment:3 by anonymous, 9 years ago

Type: Feature RequestsBugs

I understand, I didn't know about the completeness requirement, I thought I could just blindly replace std::list.

Now I wonder, how is iterator_to implemented? Is there a hidden index, indexed by address?

comment:4 by Joaquín M López Muñoz, 9 years ago

I understand, I didn't know about the completeness requirement, I thought I could just blindly replace std::list.

In fact, if my memory serves me well there's no standard requirement that std::list can be instantiated with incomplete types, you happen to be using an stdlib implementation providing this nice-to-have feature.

Now I wonder, how is iterator_to implemented? Is there a hidden index, indexed by address?

There's no black magic here. iterator_to is used in the following context:

iterator it=c.iterator_to(*p);

So, you are providing the function with the node and the container it belongs to, this is all the info required to construct the iterator (not in a general case, but it happens to be so in Boost.MultiIndex.)

Note: See TracTickets for help on using tickets.