C++ 传递唯一值引用结果编译错误
以下是示例代码:C++ 传递唯一值引用结果编译错误,c++,c++11,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
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;
}
使用名称空间std;
结构A{
A(唯一的_ptrs)
:_s(move(s)){}
独特的ptr;
};
int main(int argc,const char*argv[]{
auto&&ptr=make_unique(5);
A{ptr};//错误
A b{move(ptr)};//确定
返回0;
}
我的第一个猜测是,它不需要使用“move”就可以工作,但我在clang上得到了“调用隐式删除的复制构造函数”。也许“ptr”的类型不是右值(奇怪吗?)?有人能澄清一下吗 这里有几件事在起作用,其中大部分涉及到价值类别分类法中各个部分的标准措辞。但要点如下:
ptr
类型的推断将遵循转发引用的规则。所以是的,它将是独一无二的。但是ptr
不是右值。这是很难理解的。当然,它是您绑定到右值的引用,但现在该对象不再是未命名的,对它的引用也不再是
它现在是一个有名称的对象。直觉上,因为你可以给它赋值,所以它是一个左值(在一般意义上)。因此,它本身不会绑定到右值引用。因此,您最终尝试调用复制构造函数
要移动它,需要再次将其转换为过期值(从类型系统的角度来看)。这就是
std::move
通过返回对它的(未命名)右值引用所做的。传递一个r值:
A a{ make_unique<int>(5) };
A{make_unique(5)};
或std::移动l值
auto ptr = make_unique<int>(5);
A b{ move(ptr) };
auto ptr=make_unique(5);
A b{move(ptr)};