2016-05-13 109 views
2

我有一个类,移动任务被明确删除,因为对象不应该是可移动的。但是,如果我分配到使用这个RVO类的一个实例,编译器给我的错误:编译器不会使用复制分配而是移动?

main.cpp:12:16: note: candidate function has been explicitly deleted 

也编译器提现有的拷贝赋值运算符,但不使用它。

这里是我的代码(或(不)运行例如here):

class foo { 
public: 
    foo() {} 
    foo(foo const& r) {} 
    foo(foo&&) = delete; 

    foo const& operator=(foo const& r) { return *this; } 
    foo const& operator=(foo&& r) = delete; 
}; 

int main(int argc, char **argv) { 
    foo bar; 
    bar = foo(); 
    return 0; 
} 

我发现了一个非常类似的帖子here

我知道我可以通过使用临时避免这种情况。我想知道为什么每个编译器(我用gcc,clang和vs2013测试过)不能直接调用现有的拷贝任务?有什么我失踪?

+4

此举赋值运算符是一个更好的匹配。在考虑它被删除之前发生这种情况。 – chris

+4

删除的函数参与重载解析。 – 101010

+0

只要不删除移动assingment,一切都会很好。不动的存在会抑制默认值。 – SergeyA

回答

2

复制分配未被调用,因为(删除的)移动分配与重载分辨率更匹配。

根本不要声明移动分配。然后复制分配将被选中。隐式移动赋值运算符将不会生成,因为该类具有用户声明的复制构造函数,移动构造函数和复制赋值运算符。任何这些都将阻止生成隐式移动赋值运算符。


But if i assign to an instance of this class using RVO

没有这里涉及视网膜静脉阻塞。您创建一个临时foo并将其复制分配给一个现有的变量。复制分配不能被删除。

另外,从赋值运算符返回值是非常不寻常和低效的。

+0

'另外,从赋值运算符返回值是非常不寻常和低效的。'这是真的,也是来自erip的评论('公司喜欢慢速代码')。我正在围绕一个不是我设计的课程而只是想知道为什么会发生这样的事情...... – user1810087

0

你可以使用新的安置要做到这一点:

#include <iostream> 
#include <string> 
#include <new> 

class foo { 
public: 

    foo() {} 
    foo(foo const& r) {} 
    foo(foo&&) = delete; 

    foo const& operator=(foo const& r) { return *this; } 
    foo const& operator=(foo&& r) = delete; 
}; 

int main(int argc,char **argv) 
{ 
    foo bar; 

    //bar = foo(); 
    bar.~foo(); 
    new(&bar) foo(); 

    return 0; 
} 
相关问题