struct A
{
A();
A(const A&);
A& operator =(const A&);
A(A&&) = delete;
A& operator =(A&&) = delete;
};
struct B
{
B();
B(const B&);
B& operator =(const B&);
};
int main()
{
A a;
a = A(); // error C2280
B b;
b = B(); // OK
}
My compiler is VC++ 2013 RC.
error C2280: 'A &A::operator =(A &&)' : attempting to reference a deleted function
I just wonder why the compiler doesn't try A& operator =(const A&);
when A& operator =(A&&)
is deleted?
Is this behavior defined by the C++ standard?
The expression on the right is a temporary which means it will look for
operator=(A&&)
and sees it is deleted. Hence the error. There is no further search.=delete
does not mean "don't use me, instead use next best one". It rather means, "don't use me when you need me — instead be alone in the wild."Here is another example. If I want the instances of my class
X
to be created with onlylong
and no other type (even if it converts into long!), then I would declareclass X
as:That means, the overload resolution is performed before the compiler sees the
=delete
part — and thus results in an error because the selected overload is found deleted.Hope that helps.
When you
=delete
a function, you actually are deleting its definition.But by doing so, you are also declaring that function. Quoting from the standard [1]:
And so by doing
a = A()
, the compiler actually resolves toA::operator=(A&&)
because it has been declared (notA::operator(const A&)
, becauseA&&
is "more binding" to r-values). However with its definition being deleted, the line is ill-formed.[1] The tone of the emphasized sentence here is actually imperative. The standard directs that declaring a function
=delete
d must first appear before other declarations of it. But still, it supports the fact that deleting a function also declares the function.