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 delete key is a key on most computer keyboards which is typically used to delete either (in text mode) the character ahead of or beneath the cursor, or (in GUI mode) the currently-selected object. The key is sometimes referred to as the "forward delete" key.
= delete can be used for any function, in which case it is explicitly marked as deleted and any use results in a compiler error.
Answer: Yes, we can delete “this” pointer inside a member function only if the function call is made by the class object that has been created dynamically i.e. using “new” keyword. As, delete can only be applied on the object that has been created by using “new” keyword only.
In another way, = delete means that the compiler will not generate those constructors when declared and this is only allowed on copy constructor and assignment operator. There is also = 0 usage; it means that a function is purely virtual and you cannot instantiate an object from this class.
a = A(); // error C2280
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 only long
and no other type (even if it converts into long!), then I would declare class X
as:
struct X { X(long arg); //ONLY long - NO int, short, char, double, etc! template<typename T> X(T) = delete; }; X a(1); //error - 1 is int X b(1L); //ok - 1L is long
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.
8.4.3 Deleted definitions [dcl.fct.def.delete]
1 A function definition of the form:
attribute-specifier-seqopt decl-specifier-seqopt declarator = delete ;
is called a deleted definition. A function with a deleted definition is also called a deleted function.
But by doing so, you are also declaring that function. Quoting from the standard [1]:
4 A deleted function is implicitly inline. [ Note: The one-definition rule (3.2) applies to deleted definitions. —end note ] A deleted definition of a function shall be the first declaration of the function [...]
And so by doing a = A()
, the compiler actually resolves to A::operator=(A&&)
because it has been declared (not A::operator(const A&)
, because A&&
is "more binding" to r-values). However with its definition being deleted, the line is ill-formed.
2 A program that refers to a deleted function implicitly or explicitly, other than to declare it, 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With