传递unique_ptr右值引用结果编译错误

use*_*604 3 c++ c++11

以下是示例代码:

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;
}
Run Code Online (Sandbox Code Playgroud)

我的第一个猜测是它应该在不使用'move'的情况下工作,但我在clang上得到'调用隐式删除的复制构造函数'.也许'ptr'的类型不是rvalue(奇怪的是?)?有人可以澄清一下吗?

Sto*_*ica 5

这里有几件事情,其中​​大部分涉及价值类别分类中各部分的标准的措辞.但这是它的要点:

ptr类型的推断将遵循转发引用的规则.是的,它会是unique_ptr<int>&&.但这ptr不是一个左派.这是理解的棘手问题.它是一个你已经绑定到rvalue的引用,当然,但是现在该对象不再是未命名的,也不是对它的引用.

它现在是一个带名字的对象.直觉上,因为你可以分配它,它是一个左值(在一般意义上).因此,它不会自己绑定到右值引用.所以你最终试图调用复制构造函数.

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