3

I have a structure which conceptually has the following

class C {/* expensive class */};
struct mapping {
    std::map<std::pair<C,C>, C> the_map;
};

This is less than ideal as a large number of copies of C end up being stored. My current solution is to create a set of C and then store pointers (or iterators) in the map.

struct mapping {
    std::set<C> all_Cs;
    std::map<std::pair<C*, C*>, C*> the_map;
};

This should be safe as the_map will always be destructed before all_Cs so all pointers will be valid.

Copy construction can be done by copies the set and reconstructing the map but is it possible to efficiently implement move construction?

From what I understand, moving a set with the same allocator is required to be a constant operation which (I assume) forces the implementation to maintain the validity of pointers to objects in the set but I cannot find anything to back this up in the standard. Using this I should be able to implement a move constructor by simply moving both the set and the map and all of the pointers will correctly be owned by the new object.

Is this this reasoning correct and can I rely on this behaviour in a portable way?

ildjarn
  • 62,044
  • 9
  • 127
  • 211
Peter Ogden
  • 710
  • 5
  • 10
  • 1
    If you've moved from something, its guts are ripped out and put in the destination of whatever you're moving to. The thing moved from will be in an undetermined state, but still reusable. – Tony The Lion Apr 05 '13 at 11:15
  • Your reasoning should hold. – Xeo Apr 05 '13 at 11:16

1 Answers1

3

Move construction is guaranteed to preserve the objects in the container, by Table 99 (Allocator-aware container requirements). In addition to the constant complexity requirement (which precludes reallocating the elements), the post-condition for X u(rv) states:

u shall have the same elements as rv had before this construction;

Move assignment does not give the same guarantee. It will allocate new elements if the allocator's traits tell it not to propagate the allocator, and does not explicitly state that it won't otherwise.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644