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
noexceptyou need to make its sub-objects havenoexceptmove assignment operators.The most obvious portable way I can think of is to use a wrapper around
std::vectorwhich forces the move to benoexceptAnother 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 operatornoexceptfor other allocator types when it is known that all allocator instances compare equal.