No, this is not correct, for the reasons that Potatoswatter gave. In addition to requiring the copy / move constructor to return by value, you cannot return some types by value at all:
#include <type_traits> template<class T> T DecayType(T); template<class T> struct decay { using type = decltype(DecayType(std::declval<T>())); }; struct abstract { virtual void f() = 0; }; static_assert(std::is_same<decay<abstract&>::type, abstract>::value, ""); struct incomplete; static_assert(std::is_same<decay<incomplete&>::type, incomplete>::value, ""); struct immortal { ~immortal() = delete; }; static_assert(std::is_same<decay<immortal&>::type, immortal>::value, "");
source share