atanamir
atanamir

Reputation: 4953

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

Upvotes: 1

Views: 1089

Answers (1)

Nicol Bolas
Nicol Bolas

Reputation: 473447

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

Upvotes: 4

Related Questions