Dun*_*ndo 8 c++ unique-ptr move-semantics c++17 structured-bindings
鉴于以下代码:
#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);
}
Run Code Online (Sandbox Code Playgroud)
GetA1 不编译,出现此错误:
C2440: 'return': cannot convert from 'std::unique_ptr<B,std::default_delete<_Ty>>' to 'std::unique_ptr<A,std::default_delete<_Ty>>'
虽然GetA2编译没有错误。
我不明白为什么我需要调用std::move才能使函数工作。
编辑
只是为了澄清,正如 DanielLangr 在评论中指出的那样,我怀疑的是
std::unique_ptr<A> GetA3() {
std::unique_ptr<B> b2;
return b2;
}
Run Code Online (Sandbox Code Playgroud)
无需std::move.
现在我明白,在GetA1and 的情况下GetA2,使用结构化绑定,它恰好b是某个对象的一部分,因此必须将其移动为右值引用。
我不明白为什么我需要调用 std::move 来使函数工作。
因为对应的构造函数std::unique_ptr有一个右值引用类型的参数:
template< class U, class E >
unique_ptr( unique_ptr<U, E>&& u ) noexcept;
Run Code Online (Sandbox Code Playgroud)
有关详细信息,请参阅文档:https : //en.cppreference.com/w/cpp/memory/unique_ptr/unique_ptr
由于右值引用不能绑定b左值,因此,您不能使用(即左值)作为此构造函数的参数。
如果您想知道为什么b在return语句中将其视为左值,请参阅例如:为什么结构化绑定禁用 RVO 并在返回语句上移动?简而言之,b不是一个自动存储持续时间的变量,而是一个对元素的引用。
错误消息基本上只是说编译器找不到任何可行的转换构造函数,因此,它“无法转换...”。
通过b用std::movecall包装,您正在创建一个表达式,该表达式引用与 完全相同的对象b,但其类别是右值。这可能与该构造函数参数绑定。
| 归档时间: |
|
| 查看次数: |
279 次 |
| 最近记录: |