如果我们以 std::unique_ptr 为例,将仅 move 类型传递到接收器函数(例如获取指针所有权的构造函数)的普遍智慧是按值传入并在调用点 move 它。例如。

class Sink {
    public:
        Sink(std::unique_ptr<Foo> foo) : foo(std::move(foo)) {}

    private:
        std::unique_ptr<Foo> foo;
};

这怎么可能?编译器不应该能够立即推断出 std::unique_ptr 是仅 move 类型并拒绝使用 Sink(std::unique_ptr<Foo>) 吗?这里的按值传递规则有什么特别之处(即按值传递的东西被复制到该函数激活框架中)?

提前致谢。

最佳答案

当然,这有效,只要您将右值传递给 Sink 的构造函数或 move 参数。在这两种情况下,都会为参数调用 move 构造函数,而不是(已删除的)复制构造函数。

注意:我认为 std::move 在这里不是一个好主意,因为这样你的函数中就会有一个 move 的对象。静态分析可能会发现这一点,但它是错误的来源。

#include <memory>

struct Foo {};

class Sink {
    public:
        Sink(std::unique_ptr<Foo> foo) : foo(std::move(foo)) {}

    private:
        std::unique_ptr<Foo> foo;
};

int main() {
    // rvalue
    Sink s(std::make_unique<Foo>());

    // std::move (can be dangerous)
    auto f = std::make_unique<Foo>();
    Sink ss(std::move(f));

    // By value is not allowed
    auto ff = std::make_unique<Foo>();
  //Sink sss(ff); // BOOM!
}

Live on Wandbox

关于c++ - 如何通过值传递仅 move 类型(例如 std::unique_ptr)?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51295303/

10-11 22:49
查看更多