atanamir atanamir - 1 month ago 13
C++ Question

std::move items out of an STL container?

I'm trying to

std::move
an element out of a
std::set
and then erase it from the set:

std::set<some_type> the_set;
some_type item;

for (auto iter = the_set.begin(); iter != the_set.end(); iter++)
{
auto miter = std::make_move_iterator(iter);
item = std::move(*miter);
the_set.erase(iter);
break;
}


The compiler doesn't like it, though (MSVC 2015):

error C2280: 'some_type &some_type::operator =(const some_type &)': attempting to reference a deleted function


Seems like it's trying to use a copy constructor instead, which I don't want. How would I get it to use the move constructor? (I tried the
move_iterator
out of desperation, not sure if it's the right solution here).

Answer

std::set iterators are effectively const iterators (in C++11 and later). That way, you cannot possibly change them and break set's ordering.

And you cannot move from a const&&. So you cannot move out of a set.

C++17 will permit you to do so, but via a different API (PDF). Basically, you have to extract the node itself from the set, then move the object in the node, and then destroy the node (by letting it fall off the stack). I believe the code would look something like this:

for (auto iter = the_set.begin(); iter != the_set.end(); iter++)
{
    auto node = the_set.extract(iter);
    item = std::move(node.value());
    break;
}