The following structure fails to compile under C++11 due to the fact that I have declared the move assignment operator as noexcept
:
struct foo
{
std::vector<int> data;
foo& operator=(foo&&) noexcept = default;
};
The default move assignment operator generated by the compiler is noexcept(false)
due to the fact that std::vector<int>
's move assignment is also noexcept(false)
. This in turn is due to the fact that the default allocator has std::allocator_traits<T>:: propagate_on_container_move_assignment
set to std::false_type
. See also this question.
I believe this has been fixed in C++14 (see library defect 2103).
My question is, is there a way for me to force noexcept
upon the default move assignment assignment operator without having to define it myself?
If this is not possible, is there a way I can trick the std::vector<int>
into being noexcept
move assignable so that noexcept(true)
is passed through to my struct?
As a DR that fix should be considered a correction to C++11 and so some C++11 implementations will have already fixed it.
For the defaulted move assignment operator to be
noexcept
you need to make its sub-objects havenoexcept
move assignment operators.The most obvious portable way I can think of is to use a wrapper around
std::vector
which forces the move to benoexcept
Another similar option is to define your own allocator type with the DR 2013 fix and use that:
Another option is to use a standard library implementation such as GCC's which implements the resolution to DR 2013 and also makes
std::vector
's move assignment operatornoexcept
for other allocator types when it is known that all allocator instances compare equal.