class C
{
public:
C(C&&) = default; // (1)
C& operator=(C&&) = default; // (1)
C(C&&) noexcept = default; // (2)
C& operator=(C&&) noexcept = default; // (2)
}
As far as I know, if move constructor/assignment operator are either implicitly generated or explicitly defaulted by user (1), the compiler will decide whether these special member functions should be noexcept or not depending on whether all the members of a class provide noexcept guarantees for move operations. But what if I want to use default move special members and force them to be noexcept regardless of the underlying members exception guarantees for move operations? Is there any difference for the compiler between (1) and (2) declarations?
Ok, I found the answer in Nico's Josuttis book "C++ Move Semantics - The Complete Guide":
I asked this question because I want STL algorithms to always apply move semantics to my classes regardless of their members' exception guarantees, and I am ready to deal with
std::abortif something goes wrong. But it seems that prior to C++ 20 the only way to forcenoexceptguarantees on move special member functions was to explicitly define them, even if you don't need your own implementation. It turns out C++20 solved this by allowing us to specifynoexceptguarantees for defaulted special member functions. Of course, as in case with any othernoexceptfunction, if any of the members of a class throws during a move operation,std::abortwill be called if move constructor/assignment operator are declarednoexceptfor that class, as it was kindly pointed out by @MichaëlRoy in the comments section.