C ++ 11中已删除函数的确切语义是什么?

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 } 

我的编译器是VC ++ 2013 RC。

错误C2280:'A&A :: operator =(A &&)':尝试引用已删除的函数

我只是想知道为什么编译器不会尝试A& operator =(const A&);A& operator =(A&&)被删除?

这个行为是由C ++标准定义的吗?

 a = A(); // error C2280 

右边的expression式是一个临时的,这意味着它将查找operator=(A&&)并且看到它被删除。 因此,错误。 没有进一步的search。

=delete并不意味着“不要使用我,而是使用次最好的一个”。 它意味着,“ 当你需要我的时候不要使用我而应该单独在野外。”

这是另一个例子。 如果我想让我的类X的实例只用long就可以创build,并且没有其他的types (即使它转换成long!),那么我将声明class X

 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 

这意味着,在编译器看到=delete部分之前执行重载parsing,因此会导致错误,因为所选的重载被删除。

希望有所帮助。

当你=delete一个函数时,你实际上正在删除它的定义

8.4.3删除的定义[dcl.fct.def.delete]

1窗体的函数定义:

attribute-specifier-seqopt decl-specifier-seqopt declarator = delete;

被称为删除的定义 。 具有删除定义的function也被称为删除function

但是通过这样做,你也正在声明这个function。 引用标准[1]

4删除的函数隐式内联。 [注意:单定义规则(3.2)适用于已删除的定义。 – 注意]function的删除定义应该是function的第一个声明 […]

因此,通过执行a = A() ,编译器实际上parsing为A::operator=(A&&)因为它已被声明(不是A::operator(const A&) ,因为A&&对r值“更具约束力” )。 但是,由于其定义被删除,该行是不合格的。

2除了声明外,隐式或显式引用已删除函数的程序是不合格的。


[1]这里强调句子的语气实际上是必要的。 该标准指示声明一个函数=delete d必须先出现在其他声明之前。 但是,它还支持删除函数也声明函数的事实。

Interesting Posts