문제

In c++11, std::unordered_set container provides both an insert overload and a new function emplace so that it can be used with non copy-constructible keys, for example std::unique_ptr.

What happens when you want to remove one of these keys? Is auto temp = std::move(*some_iterator) valid? Is there some function that allows us to erase an element and move it into a temp simultaneously?

Edit: I tried to keep it short, sweet and simple, but to be more clear:

  • Is there an iterator adapter (possibly move_iterator?) that will let me move an element from a container, and erase that iterator?
  • If not, why not? Shouldn't future c++ include this kind of interface?

The situation seems to be impossible: you cannot invalidate a key before removing it, and you cannot access it after removing it.

도움이 되었습니까?

해결책

For std::unordered_set<T> the member emplace() makes it unnecessary for the objects to be movable, either: you can emplace() non-movable objects into the container.

To answer the question: you can't std::move() elements out of a std::unordered_set<T> because the elements are all const and const objects can't be moved. When you erase() an std::unique_ptr<T> from an std::unordered_set<std::unique_ptr<T>> the pointed to object will be deleted: there is no interface which allows you to recover the pointer while erase()ing the element. Nor is there a splice() member to stick the element into another container where it can be ignored until it is time to get rid of it.

다른 팁

My solution is simply to put the elements in std::shared_ptr. This way you can copy them around, and then eventually move the element out of the shared_ptr.

The cost of this, programming-wise, is that you have to define the hash function yourself.

Assuing you're putting std::string in the set:

struct MyHasher
{
    size_t operator()(const std::shared_ptr<std::string>& element) const
    {
        return std::hash<std::string>()(*element);
    }
};

And then you make the unordered_set like this:

std::unordered_set<std::string,MyHasher> the_set;

And now, you can move the elements around all you want.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top