Associative STL Containers: Erasing and Returning (Non-Copyable) Item

I use STL associative containers ( std::setand std::map) with keys that contain an instance std::unique_ptr<>. A key definition is equivalent to the 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); }
}

Associative STL containers (for example, with C ++ 11) are not known to have a way to get a non-constant key reference for a move. And my keys cannot be copied, so C ++: removing an item from the container and returning it does not work.

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

My current solution is as follows:

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;
}
+4
source share
1 answer

:

. .

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3586.pdf

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3645.pdf

, . undefined. , . , , . , .

UB , const ( ). const ( ) - UB.

N3586 , :

move_only_type mot = move(*s.remove(s.begin()));

move_only_key mok = move(m.remove(m.begin())->first);

N3586/N3645 . , , . , std:: lib UB . .

+6

Source: https://habr.com/ru/post/1569158/


All Articles