作者:059586768803wsq | 来源:互联网 | 2022-12-10 12:33
如何解决《如何从std::optional<QByteArray>获取QByteArray并离开std::nullopt而不需要额外的mallocs?》经验,为你挑选了2个好方法。
我需要编写一个函数来获取optional
底层数组的所有权.
在Rust中,它是通过这种方式完成的:
fn my_func(f: &mut Option>) -> Box<[u8]> {
//how to do "take" in c++17?
f.take().unwrap()
}
我知道std::move
,但据我所知,这段代码将为malloc
新数组,交换指针和删除不需要的数据QByteArray
:
std::optional optarr = ...
QByteArray optarr = std::move(*myopt);
optarr.reset()
有没有办法和Rust一样(也就是说,没有为临时分配内存QByteArray
)?
1> PaulR..:
你的假设std::move
是错误的.粗略地说std :: move强制转换为右值引用,本身不会生成任何实际代码.以下行将QByteArray
通过调用其移动构造函数在堆栈上创建一个.
QByteArray optarr = std::move(*myopt);
移动构造函数Data
从另一个QByteArray 初始化指针,并用指向共享空数据的指针替换另一个数据指针.没有malloc
涉及,只有两个指针分配.
move构造函数的实现如下所示:
inline QByteArray(QByteArray && other) Q_DECL_NOTHROW : d(other.d) { other.d = Data::sharedNull(); }
所以你的代码实际上正在做你想要的.
2> Barry..:
C++中的等效†函数是:
auto func(optional&& o) -> QByteArray
{
return std::move(o).value();
}
std::move(o)
给你一个类型的右值optional
.调用value()
该右值会给你一个QByteArray&&
(如果o
被释放则抛出).该rvalue类型QByteArray
用于移动构造返回对象.这种移动结构很便宜,只需几个指针分配 - 不会发生内存分配.
†几乎相当于.请注意,o
这里并没有结束的分离optional
,与生锈.它还在忙着,只是空着QByteArray
.如果真的需要,真的相当于:
auto func(optional&& o) -> QByteArray
{
QByteArray result = std::move(o).value(); // NB: not a reference
o.reset(); // or '= nullopt', or '= {}'
return result; // NB: no need to move
}