2

If I have a std::list, for example, and I use std::move() to move its information into a std::map, is it safe to reuse the list by populating it with more data so that I can add more entries to the map? I vaguely remember being told by another programmer that std::move() puts things in an unknown state so you shouldn't reuse them after, but I would just like to confirm since I can't seem to find any information on this just by searching around.

If it's not safe, then would calling clear() on the list after moving it make it OK to reuse?

Here's an example of what I'm doing:

// Create the initial list, give it some data, then move it into the map.
typedef std::list<std::pair<string, uint16>> TListType;
TListType data;
data.push_back(std::make_pair("some string", 0));
data.push_back(std::make_pair("some other string", 0));

std::map<uint32, TListType> mappedData;
mappedData.insert(std::make_pair(0, std::move(data)));

// Insert more data into the list, then move into the map as a new entry.
data.push_back(std::make_pair("new strings", 9));
mappedData.insert(std::make_pair(1, std::move(data)));

The reason I have to do all this ugly mess is because I can't use initializer lists and I don't have Boost, so I'm a bit limited in how to initialize complicated data structures.

Justin G
  • 776
  • 1
  • 10
  • 25

1 Answers1

4

After moving from the standard C++ library classes, they are in an unspecified state but otherwise entirely usable. The relevant section is 17.6.5.15 [lib.types.movedfrom]:

Objects of types defined in the C++ standard library may be moved from (12.8). Move operations may be explicitly specified or implicitly generated. Unless otherwise specified, such moved-from objects shall be placed in a valid but unspecified state.

None of the containers specifies otherwise (as far as I know).

From the sounds of it, you are actually moving the elements, though. However, for these apply rather similar restrictions based on the definition of what MoveConstructible and MoveAssignable means (from section 17.6.3.1 [utility.arg.requirements]; rv is the argument to either move constructino or move assignment):

rv’s state is unspecified [ Note:rv must still meet the requirements of the library component that is using it. The operations listed in those requirements must work as specified whether rv has been moved from or not. —end note ]

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380