c++ - 为什么我需要移动`std::unique_ptr`
问题描述
给定以下代码:
#include <iostream>
#include <memory>
struct A {};
struct B : public A {};
std::pair<bool, std::unique_ptr<B>> GetBoolAndB() {
return { true, std::make_unique<B>() };
}
std::unique_ptr<A> GetA1() {
auto[a, b] = GetBoolAndB();
return b;
}
std::unique_ptr<A> GetA2() {
auto [a, b] = GetBoolAndB();
return std::move(b);
}
GetA1
无法编译,出现以下错误:
C2440: 'return': cannot convert from 'std::unique_ptr<B,std::default_delete<_Ty>>' to 'std::unique_ptr<A,std::default_delete<_Ty>>'
whileGetA2
编译没有错误。
我不明白为什么我需要调用std::move
才能使函数工作。
编辑
只是为了澄清,正如 DanielLangr 在评论中指出的那样,我的怀疑是关于
std::unique_ptr<A> GetA3() {
std::unique_ptr<B> b2;
return b2;
}
无需std::move
.
现在我明白在 and 的情况下GetA1
,GetA2
对于结构化绑定,它恰好b
是某个对象的一部分,因此必须将其移动以成为右值引用。
解决方案
我不明白为什么我需要调用 std::move 来使函数工作。
因为对应的构造函数std::unique_ptr
有一个右值引用类型的参数:
template< class U, class E >
unique_ptr( unique_ptr<U, E>&& u ) noexcept;
有关详细信息,请参阅文档:https ://en.cppreference.com/w/cpp/memory/unique_ptr/unique_ptr
由于右值引用不能绑定左值,因此,您不能使用b
(左值)作为此构造函数的参数。
如果您想知道为什么b
在语句中被视为左值return
,请参阅例如:为什么结构化绑定禁用 RVO 并继续返回语句?简而言之,b
不是具有自动存储持续时间的变量,而是对pair元素的引用。
错误消息基本上只是说编译器找不到任何可行的转换构造函数,因此,它“无法转换......”。
b
通过使用call包装std::move
,您正在创建一个引用与 相同的对象的表达式b
,但它的类别是右值。这可能与该构造函数参数绑定。
推荐阅读
- ruby-on-rails - 为什么 HERE oauth2 令牌请求 api 使用 Rails 返回 401300,但使用 Postman 可以正常工作?
- docker - 如何从多阶段 docker 构建连接到 BitBucket 服务容器?
- html - 如何进行这种响应式设计?
- split - Power BI:按字符串从其他列拆分列
- arrays - 从 API 数组获取数据的问题
- python - 这是 super() 在我的代码中的工作方式吗?
- flutter - 引发了另一个异常:Null check operator used on a null value
- python - 在具有相同主体的python中创建多个动态函数
- sql - 情况下......对于子组
- javascript - html 复选框关联数组 - 如何在 javascript 中访问此数组?