这是示例代码:

using namespace std;
struct A {
    A(unique_ptr<int> s)
    : _s(move(s)){}

    unique_ptr<int> _s;
};

int main(int argc, const char * argv[]) {

    auto&& ptr = make_unique<int>(5);
    A a{ptr}; // Error
    A b{move(ptr)}; // OK
    return 0;
}

我的第一个猜测是它应该在不使用“移动”的情况下工作,但是我在 clang 上得到了“调用隐式删除的复制构造函数”。也许“ptr”的类型不是右值(奇怪?)?有人可以澄清这一点吗?

最佳答案

这里有几件事情在起作用,其中大部分涉及值(value)类别分类法中各个部分的标准措辞。但这是它的要点:
ptr 类型的推导将遵循转发引用的规则。所以是的,它将是 unique_ptr<int>&& 。但是 ptr 不是右值。这是很难理解的事情。这是一个您绑定(bind)到右值的引用,当然,但现在对象不再是未命名的,对它的引用也不再是未命名的。

它现在是一个有名字的对象。直观地说,由于您可以为其赋值,因此它是一个左值(一般意义上)。因此,它本身不会绑定(bind)到右值引用。所以你最终试图调用复制构造函数。

要移动它,您需要再次将其转换为过期值(从类型系统的角度来看)。这就是 std::move 通过返回一个(未命名的)右值引用来做的。

关于c++ - 传递unique_ptr右值引用结果编译错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46783662/

10-15 06:24