MSVC不能返回一个可以复制但不能移动的对象

2021-02-28 18:16

在处理复制省略时我遇到了这个奇怪的行为:类对象{public:Obj()=default;Obj(Objamp;){std::coutlt;lt;<;std::endl;}}};Obj f1(){Obj o;retur

解答动态

  • F1()上没有错误是clang和gcc中的一个错误。它是在clang的主干顶端修复的。
    f1()不符合强制删除副本的条件。
    Deleted函数参与重载解析。如果选择它们作为最佳重载,则程序的格式是错误的。在F1()中,删除的移动构造函数由过载解决方案.2 in f2()选择,如C++ 17,保证复制/移动删除,因此不执行移动/复制构造函数上的过载分辨率。在C++ 11/14中,f2-()也是一个错误(同样错误(f1)),因为复制/移动删除不保证。2 也看到这个准则:永远不要删除那些特殊的移动成员,它是在C++ 17之前写的。
    OH,我感到惭愧,我刚刚意识到另一个答案是Howard Hinnant。有一个人的作品让我明白了我在这里痛苦地试图解释的东西,这有点可笑……因为copy和move构造函数都是声明的,所以它们都是存在,尤其是在这里,您需要小心地定义自己的复制构造函数;如果没有这一点,它将被定义为deleted(参见本演示文稿的第28页)。第28页deleted方面只是定义的细节,但它们实际上都被声明为可以重载分辨率f1()如果发生复制省略,则不需要在复制构造函数和移动构造函数之间进行选择;这些都不是用过了。开其他的另一方面,如果没有出现复制省略,则必须选择最佳重载来构造结果;这里是move构造函数,因为它存在(声明了,请参见此处),最后发现定义为deleted,但为时已晚,已经做出了选择。
    在f2()中,显式请求显式复制,那么复制构造函数是最好的选择。
    这是相当令人困惑的,当我们读取=删除时,我们认为?这不能在重载解析中选择?但这是错误的;=只有在重载解析之后,当发现更好的匹配时,才考虑删除。

    • End

    免责声明:

    本页内容仅代表作者本人意见,若因此产生任何纠纷由作者本人负责,概与琴岛网公司无关。本页内容仅供参考,请您根据自身实际情况谨慎操作。尤其涉及您或第三方利益等事项,请咨询专业人士处理。