A question about when a defaulted move assignment operator is deleted

Platform: linux, x86_84, clang++3.3 (trunk 178517), g++4.7.2

I'm learning C++11 standard, and often write some code to test clang++.
But sometimes I'm not sure whether my understanding is right when clang++
does not work as my expecting.

12.8/p23 in N3290:

This is not a forum for learning about C++; stackoverflow.com would be a better place to ask such questions.

This is not a forum for learning about C++; stackoverflow.com would be a
better place to ask such questions.

Platform: linux, x86_84, clang++3.3 (trunk 178517), g++4.7.2

I'm learning C++11 standard, and often write some code to test clang++.
But sometimes I'm not sure whether my understanding is right when clang++
does not work as my expecting.

12.8/p23 in N3290:
--------------------------------------------------------
A defaulted copy/move assignment operator for class X is defined as
deleted
if X has:
  ...
  -- for the move assignment operator, a non-static data member or direct
base class with a type that does
     not have a move assignment operator and is not trivially copyable, or
any direct or indirect virtual
     base class.
--------------------------------------------------------
Does it partially mean that the defaulted move assignment operator for
class
X is defined as deleted if X has any direct or indirect virtual base
class?

In the latest draft of the standard, that bullet has been removed. (Since
virtual bases can be assigned multiple times by defaulted assignment
operators, this means that the compiler might generate a broken move
assignment operator for classes which inherit from the same virtual base
through multiple inheritance paths. I argued against this, but the
committee seemed to prefer the simpler rule.)

We also have this (which doesn't help in your example, but is relevant in
general):

"A defaulted move assignment operator that is defined as deleted is
ignored by overload resolution (13.3, 13.4)."

OK, that's weird. How is that different to having it not provided at all?
(& it seems really unfortunate that deleted definitions do anything other
than cause compilation errors - affecting overload resolution, etc, adds
some substantial wrinkles to the model)

You can still name it in a friend declaration. And it seemed weirder for “blah = delete;” to not declare ‘blah’ at all.

I think it makes sense. For example, if you delete the copy ctor, the compiler can tell you - when you want to copy - that it’s not possible, because the the copy ctor was deleted.

In addition, and more importantly, it allows this to behave as expected:

class Base {};
class Derived : public Base {};

struct Foo
{
Foo(Base* o) { … }
Foo(Derived* o) = delete;
};

Foo(new Derived); // error: that overload is deleted

Now if the = delete would just “remove” that overload, then the last line would compile as a call to Foo(Base*), with an implicit derived-to-base cast.

Gabor

I think it makes sense. For example, if you delete the copy ctor, the compiler can tell you - when you want to copy - that it’s not possible, because the the copy ctor was deleted.

In addition, and more importantly, it allows this to behave as expected:

class Base {};
class Derived : public Base {};

struct Foo
{
Foo(Base* o) { … }
Foo(Derived* o) = delete;
};

Foo(new Derived); // error: that overload is deleted

Now if the = delete would just “remove” that overload, then the last line would compile as a call to Foo(Base*), with an implicit derived-to-base cast.

I agree, but that’s not the case we’re talking about.