samedi 27 décembre 2014

STL associative containers: erasing and getting back the (noncopyable) element

I am using STL associative containers (std::set and std::map) with keys which hold a std::unique_ptr<> instance. The key definition is equivalent to following:



struct Key
{
std::unique_ptr<Object> object;
bool operator== (const Key& rhs) const { return object->equal (*rhs.object); }
bool operator< (const Key& rhs) const { return object->less (*rhs.object); }
}


It is known that STL associative containers (esp. since C++11) do not have a way to obtain a non-const reference to the key to move from. And my keys are noncopyable, so c++: Remove element from container and get it back does not work.


Is there a non-UB way to overcome this problem?


My current solution is following:



template <typename T>
using map_pair_type = std::pair<typename T::key_type, typename T::mapped_type>;

template <typename T>
typename T::value_type take_set (T& container, typename T::iterator iterator)
{
typename T::value_type result = std::move (const_cast<typename T::value_type&> (*iterator));
container.erase (iterator);
return result;
}

template <typename T>
map_pair_type<T> take_map (T& container, typename T::iterator iterator)
{
map_pair_type<T> result {
std::move (const_cast<typename T::key_type&> (iterator->first)),
std::move (iterator->second)
};
container.erase (iterator);
return result;
}

Aucun commentaire:

Enregistrer un commentaire