gpt4 book ai didi

c++ - 复制/move 省略与显式删除的复制/move 构造函数

转载 作者:搜寻专家 更新时间:2023-10-31 01:06:32 24 4
gpt4 key购买 nike

我想知道何时应用(或允许应用)复制/move 省略显式deleted 复制/move 构造函数和非deleted 复制/move 构造函数。以下是具体内容:

  1. 显式delete复制构造函数或 move 构造函数能否被删除?通过跳过 deleted copy ctor 和/或 deleted move ctor 尝试从另一个相同类型的对象或临时对象构造对象是否允许成功?

    这是 VC12 中发生的事情(我不确定是否有禁用复制/move 省略的选项):

    #include <iostream>

    struct Foo {
    Foo() { std::cout << "default ctor\n"; }
    Foo(Foo const&) = delete;
    Foo(Foo&&) = delete;
    };

    int main() {
    // ----Output------
    Foo{ Foo() }; // "default ctor"
    Foo f; // "default ctor"
    Foo{ std::move(f) }; // error C2280: 'Foo::Foo(Foo &&)' : attempting to reference a deleted function
    Foo{ f }; // error C2280: 'Foo::Foo(const Foo &)' : attempting to reference a deleted function
    }

    即使 IntelliSense 提示 Foo{ Foo() };: Error: function “Foo::Foo(Foo &&)” ... cannot be referenced – 它已被删除函数,编译器不会在那里提示,所以该行仍然可以编译。

  2. 为什么 Foo{ Foo() }; 有效,但 Foo{ std::move(f) }; 无效?如果一个调用省略了 move ctor,那么另一个不应该吗?

  3. 为什么 Foo{ Foo() }; 有效,但 Foo{ f }; 无效?这种选择性看起来很随意。这种右值引用优先于 const 引用的任意偏好(反之亦然)似乎不适用于非 ctor 方法;在调用中,如果 deleted 重载比非 deleted 重载具有更高的重载解析优先级,则 delete d 一个会阻塞非deleted 一个,导致编译器错误:

    struct Bar {
    void g(int const&) {}
    void g(int&&) = delete;
    };

    //…
    Bar b;
    b.g(2); //error C2280: 'void Bar::g(int &&)' : attempting to reference a deleted function
    // ^ Would have compiled had function `g(int&&)` been commented out.

    根据该逻辑,deleted Foo(Foo&&) 不应在争论不是暂时的;在这种情况下,Foo(Foo&&) 的重载解析优先级低于 Foo(Foo const&)

  4. 我在 g++ 4.8 中尝试了相同的 Foo 示例,禁用复制省略(通过标志 -fno-elide-constructors)并再次启用它。两个 g++ 试验都给出了:

    错误:使用已删除的函数 'Foo::Foo(Foo&&)' 用于 Foo{ Foo() };

    错误:使用已删除的函数 'Foo::Foo(const Foo&)' 用于 Foo{ f };

    哪个编译器是正确的?

最佳答案

Ms VC++ 有一个非常古老的众所周知的错误。来自 C++ 标准

[ Note: This two-stage overload resolution must be performed regardless of whether copy elision will occur. It determines the constructor to be called if elision is not performed, and the selected constructor must be accessible even if the call is elided. —end note ]

关于c++ - 复制/move 省略与显式删除的复制/move 构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20589622/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com