Open MathiasMagnus opened 1 day ago
Arguably a duplicate of #1036.
It's unfortunate that
unordered_map
's move constructor is not noexcept
due to several reasons, andvector
can't reliably know that unordered_map<int, move_only_type>
is move-only,so copy construction is attempted, which cause hard error (seems to be UB in standard wording).
Given the existence of types whose copyability is indeterminate - in the Standard Library itself! - I think the requirement in [vector.modifiers]/2 that:
If an exception is thrown while inserting a single element at the end and
T
isCpp17CopyInsertable
oris_nothrow_move_constructible_v<T>
istrue
, there are no effects. Otherwise, if an exception is thrown by the move constructor of a non-Cpp17CopyInsertable
T
, the effects are unspecified.
is unimplementable. I'd greatly prefer that we ignore this requirement by having vector reallocation always move instead of copy and submit an LWG issue to get the requirement fixed. Sometimes moving when we "should" copy is a much smaller bug than vector
being broken by copyability-indeterminate types, and nobody is going to be surprised that vector
moves instead of copying in 2025: C++ got move semantics 14 years ago.
I'll mark this https://github.com/microsoft/STL/labels/decision%20needed for now and we'll see if other maintainers can talk me down during the weekly sync meeting.
We talked about this at the weekly maintainer meeting and we believe this merits a Library Evolution issue. We would like to see @CaseyCarter's suggestion adopted - vector
should just always move, and not worry about achieving the strong EH guarantee through move-if-noexcept logic. The effects of this would be, for our implementation:
vector
to achieve strong EH on every conceivable codepath where it's theoretically required) is hugely against the strong EH guarantee for container insertions, which he has never seen relied upon in production, and is especially negative on providing this guarantee for anything beyond push_back
/emplace_back
, so he thinks there's no real loss here.For other implementations (where their container-internal sentinel nodes don't result in throwing moves), this issue still theoretically impacts them, but a user has to bring them a type with a throwing move ctor (which can be fairly easily obtained - just forget to mention noexcept
on your move!!). In that case all of the same considerations apply, as our implementation is unique only about the do-containers-have-throwing-moves-due-to-dynamically-allocated-sentinel-nodes issue - our vector
's behavior in response to whether an element has a throwing move is 100% Standard.
Describe the bug
vector
andunordered_map
seem to interact in an unexpected way. I canresize
avector
of move-only type, I canemplace
into anunordered_map
of move-onlymapped_type
, but MS-STL won't allow me toresize
avector
ofunordered_map
of move-onlymapped_type
.Command-line test case
Expected behavior
Have the code compile, like libstdc++ allows this.
Versions
Visual Studio
MSVC
STL
Additional context
Obligatory Godbolt