I feel your pain, really.
Some std::implementations will mark the move members of containers as noexcept
, at least conditional on the allocator properties, as an extension. You can adapt your code to automatically take advantage of these extensions, for example:
class Stuff {
std::vector<int> bulk;
// ...
public:
Stuff(Stuff&& o)
noexcept(std::is_nothrow_move_constructible<std::vector<int>>::value)
: bulk(std::move(o.bulk))
{}
Stuff& operator=(Stuff&&)
noexcept(std::is_nothrow_move_assignable<std::vector<int>>::value)
{ /* appropriate implementation */ }
};
And you can even test whether or not your type does have noexcept move members:
static_assert(std::is_nothrow_move_constructible<Stuff>::value,
"I hope Stuff has noexcept move members");
static_assert(std::is_nothrow_move_assignable<Stuff>::value,
"I hope Stuff has noexcept move members");
libc++ in particular does have noexcept move members for all of its containers, whenever the allocator allows, and std::allocator
always allows the container move members to be noexcept.