[cfe-dev] Move constructor forces copy assignment to be implicitly defaulted?
Howard Hinnant
hhinnant at apple.com
Mon May 28 15:21:59 PDT 2012
On May 28, 2012, at 4:26 PM, Suman Kar wrote:
> A quick question:
>
> struct A {};
>
> struct B : A { ~B() {} };
>
> A makeA() {
> A a;
> return a;
> }
>
> B makeB() {
> B b;
> return b;
> }
>
> int main() {
> A a = makeA();
> B b = makeB();
> }
>
> Is it correct to assume that A will be moved and B will not?
Yes.
> Should a
> diagnostic be required for the call to makeB?
No. B should be allowed to to suppress an implicit move constructor. The implicit version might do the wrong thing.
But you can create your own compile-time diagnostic.
#include <type_traits>
#include <string>
struct A
{
std::string s;
};
static_assert(std::is_nothrow_move_constructible<A>::value,
"A should be nothorw move constructible");
struct B
: public A
{
~B();
};
static_assert(std::is_nothrow_move_constructible<B>::value,
"B should be nothorw move constructible");
A makeA() {
A a;
return a;
}
B makeB() {
B b;
return b;
}
int main() {
A a = makeA();
B b = makeB();
}
test.cpp:18:1: error: static_assert failed "B should be nothorw move constructible"
static_assert(std::is_nothrow_move_constructible<B>::value,
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
Since the move constructor in B has been suppressed, it is no longer nothrow to move B. Now if you add:
B() = default;
B(B&&) = default;
then everything will compile.
Howard
More information about the cfe-dev
mailing list