I see a couple of options for you and a missed opportunity on the part of the standards committee that would easily solve your problem.
N3586 suggested a solution to your problem.
std::pair<iterator, bool> insert(Key const& value) { if (m_set.size() < m_size) return m_set.insert(value); auto last = std::prev(m_set.end()); if (Compare()(value, *last)) { auto temp = m_set.remove(last); *temp = value; return m_set.insert(temp); } return std::make_pair(last, false); }
In this hypothetical rewrite, temp is node_ptr , which allows non-constant access to node value_type . You can remove the node, write to it and reinsert it, all without any allocation for the nodes.
The committee politely declined the offer.
A custom allocator for std::set can do the trick in a less elegant way. Such a allocator will simply cache nodes, and your existing insert will work. One of the minor drawbacks of this approach is that while a custom allocator does not free your node from freeing it, it cannot destroy your Key and then is constructed when you change it. Some types are more effective in the appointment than in the cycle of destruction. And sometimes the former may be noexcept , while the latter cannot be.
In general, I see the custom allocator approach as a last resort. You can make it work. But this requires carefully planned and non-intuitive code.
The use of push_heap , pop_heap . However, using it is inconvenient if you really need an iterator for an inserted or equal element. If you can deal with the void return type, it might look like this:
void insert(Key const& value) { if (m_set.size() < m_size) { m_set.push_back(value); std::push_heap(m_set.begin(), m_set.end(), Compare{}); } if (Compare()(value, m_set.front())) { std::pop_heap(m_set.begin(), m_set.end(), Compare{}); m_set.back() = value; std::push_heap(m_set.begin(), m_set.end(), Compare{}); } }
But it is inconvenient to look for a heap for the newly inserted value, and push_heap does not provide this information.
Another option is a sorted vector + insertion sort. You will have to write the insertion sort yourself, but this is a relatively small programming task. The reason you want to sort the inserts is because you will always sort the sorted array, except for the last element. And insertion sorting is optimal for this job.
None of these solutions are ideal, and no one but N3586 offers anything that comes close to an out of the box solution, i.e. Doesn't require more than a few lines of code. And N3586 does not exist. If you think it should exist, contact your C ++ national authority representative and tell them about it. Or take care of the C ++ committee itself and be nice.