Created
November 29, 2015 20:07
-
-
Save Irfy/9e93f166c9d0edb7e4a7 to your computer and use it in GitHub Desktop.
Unintuitive move ctor behavior (gcc 5.2 in gnu++11 mode)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define IMPLICIT_DELETE_MEMBER 0 | |
#define DEFAULT_KEYWORD_INSIDE 0 | |
#include <utility> | |
#include <iostream> | |
struct Explicit { | |
Explicit() = default; | |
Explicit(const Explicit&) { std::cout<<"Explicit-Copy called\n"; } | |
Explicit(Explicit&&) noexcept { std::cout<<"Explicit-Move called\n"; } | |
}; | |
struct ExplicitDelete { | |
ExplicitDelete() = default; | |
ExplicitDelete(const ExplicitDelete&) = default; | |
ExplicitDelete(ExplicitDelete&&) noexcept = delete; | |
}; | |
struct ImplicitDelete : ExplicitDelete {}; | |
static_assert(std::is_move_constructible<Explicit>::value, ""); | |
static_assert(!std::is_move_constructible<ExplicitDelete>::value, ""); | |
static_assert(std::is_move_constructible<ImplicitDelete>::value, ""); | |
static_assert(std::is_nothrow_move_constructible<Explicit>::value, ""); | |
static_assert(!std::is_nothrow_move_constructible<ExplicitDelete>::value, ""); | |
static_assert(std::is_nothrow_move_constructible<ImplicitDelete>::value, ""); | |
struct MyStruct { | |
MyStruct() = default; | |
MyStruct(const MyStruct&) = default; | |
#if DEFAULT_KEYWORD_INSIDE | |
MyStruct(MyStruct&&) noexcept = default; | |
#else | |
MyStruct(MyStruct&&) noexcept; | |
#endif | |
Explicit exp; // will tell us whether an actual move was performed on MyStruct | |
#if EXPLICIT_DELETE_MEMBER | |
ExplicitDelete del; // disallows move on MyStruct because its move ctor is deleted | |
#else | |
ImplicitDelete del; // allows move on MyStruct even though its move ctor is deleted | |
#endif | |
}; | |
#if ! DEFAULT_KEYWORD_INSIDE | |
inline MyStruct::MyStruct(MyStruct&&) noexcept = default; | |
#endif | |
static_assert(std::is_move_constructible<MyStruct>::value, ""); | |
#if EXPLICIT_DELETE_MEMBER | |
static_assert(!std::is_nothrow_move_constructible<MyStruct>::value, ""); | |
#else | |
static_assert(std::is_nothrow_move_constructible<MyStruct>::value, ""); | |
#endif | |
int main() { | |
MyStruct s1; | |
MyStruct s2(std::move(s1)); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment