[英]How to take QByteArray from std::optional<QByteArray> and leave std::nullopt without additional mallocs?
I need to write a function that takes ownership of an optional<QByteArray>
's underlying array. 我需要编写一个函数来获取optional<QByteArray>
的底层数组的所有权。
In Rust, it is done by this way: 在Rust中,它是通过这种方式完成的:
fn my_func(f: &mut Option<Box<[u8]>>) -> Box<[u8]> {
//how to do "take" in c++17?
f.take().unwrap()
}
I know about std::move
, but as far as I understand, this code will malloc
data for a new array, swap pointers, and drop unneeded QByteArray
: 我知道std::move
,但据我了解,这段代码将为新数组的malloc
数据,交换指针和删除不需要的QByteArray
:
std::optional<QByteArray> optarr = ...
QByteArray optarr = std::move(*myopt);
optarr.reset()
Is there any way to do this as well as in Rust (that is, without allocating memory for temporary QByteArray
)? 有没有办法和Rust一样(也就是说,没有为临时QByteArray
分配内存)?
Your assumption about std::move
is wrong. 你对std::move
假设是错误的。 Roughly speaking std::move casts to an rvalue reference, no actual code is generated in itself by that. 粗略地说std :: move强制转换为右值引用,本身不会生成任何实际代码。 The following line will create a QByteArray
on the stack by calling its move constructor. 以下行将通过调用其移动构造函数在堆栈上创建QByteArray
。
QByteArray optarr = std::move(*myopt);
The move constructor initializes the Data
pointer from the other QByteArray and replaces the other's data pointer with pointer to shared empty data. 移动构造函数从另一个QByteArray初始化Data
指针,并用指向共享空数据的指针替换另一个数据指针。 No malloc
is involved, just two pointer assignments. 不涉及malloc
,只有两个指针分配。
The implementation of the move constructor looks like this: move构造函数的实现如下所示:
inline QByteArray(QByteArray && other) Q_DECL_NOTHROW : d(other.d) { other.d = Data::sharedNull(); }
So your code is actually doing what you want. 所以你的代码实际上正在做你想要的。
The equivalent † function in C++ would be: C ++中的等效†函数是:
auto func(optional<QByteArray>&& o) -> QByteArray
{
return std::move(o).value();
}
std::move(o)
gives you an rvalue of type optional<QByteArray>
. std::move(o)
为您提供了一个optional<QByteArray>
类型的右值。 Invoking value()
on that rvalue gives you a QByteArray&&
(or throws if o
is disengaged). 在该右值上调用value()
会为您提供QByteArray&&
(如果o
被QByteArray&&
,则抛出)。 That rvalue of type QByteArray
is used to move construct the return object. QByteArray
类型的右值用于移动构造返回对象。 This move construction is cheap, just a few pointer assignments - no memory allocation happens. 这种移动结构很便宜,只需几个指针分配 - 不会发生内存分配。
† Almost equivalent. †几乎相当于。 Note that o
here does not end up as a disengaged optional
, unlike in Rust. 请注意, o
不像Rust中那样最终作为一个脱离的optional
。 It is still engaged, just holding an empty QByteArray
. 它仍在使用,只是持有一个空的QByteArray
。 Truly equivalent, if really desired, would be: 如果真的需要,真的相当于:
auto func(optional<QByteArray>&& o) -> QByteArray
{
QByteArray result = std::move(o).value(); // NB: not a reference
o.reset(); // or '= nullopt', or '= {}'
return result; // NB: no need to move
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.