Closed AndyVenikov closed 1 year ago
Hi,
Boost.MultiIndex insertion does indeed not modify the value_type&&
passed if insertion is unsuccessful. The problem with this line
ordered_view.insert(std::move(new_element))
is that insert
expects a std::unique_ptr<Base>&&
and you're passing a std::unique_ptr<Derived>&&
: the way std::unique_ptr
's implicit construction works, this creates a temporary std::unique_ptr<Base>&&
to which the value of
new_element
is transferred. All of this happens before Boost.MultiIndex is even called, and the net result is that new_element
will become empty regardless of whether insertion is successful or not.
One possible user-side workaround is to use something like this:
template<typename Container, typename Derived>
auto insert_unique_ptr(Container& c, std::unique_ptr<Derived>&& p)
{
typename Container::value_type pb = std::move(p);
auto res = c.insert(std::move(pb));
p.reset(static_cast<Derived*>(pb.release()));
return res;
}
(https://godbolt.org/z/P5KW6q585)
Closing this issue as a non-bug.
I completely missed the implicit conversion required here. Thank you very much for point this out! And sorry for the noise.
If we want to follow std::set::insert, then insert should have no effect if insertion did not take place. Otherwise, insert is unusable in cases when collisions are expected as loosing the input argument is an unlikely intent by the caller.
Reproduction: https://godbolt.org/z/bofeMo8fd