Skip to content

Instantly share code, notes, and snippets.

@Irfy
Created November 29, 2015 20:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Irfy/9e93f166c9d0edb7e4a7 to your computer and use it in GitHub Desktop.
Save Irfy/9e93f166c9d0edb7e4a7 to your computer and use it in GitHub Desktop.
Unintuitive move ctor behavior (gcc 5.2 in gnu++11 mode)
#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