代码之家  ›  专栏  ›  技术社区  ›  chabapok

如何从std::optional<qbytearray>中获取qbytearray,并在没有附加malloc的情况下离开std::nullopt?

  •  3
  • chabapok  · 技术社区  · 7 年前

    我需要编写一个拥有 optional<QByteArray> 的基础数组。

    在生锈的情况下,是这样做的:

    fn my_func(f: &mut Option<Box<[u8]>>) -> Box<[u8]> {
         //how to do "take" in c++17?
         f.take().unwrap()
    }
    

    我知道 std::move ,但据我所知,此代码将 malloc 新数组的数据、交换指针和不需要的丢弃 QByteArray 以下内容:

    std::optional<QByteArray> optarr = ...
    QByteArray optarr = std::move(*myopt);
    optarr.reset()
    

    有什么方法可以做到这一点吗?也就是说,不需要为临时的 Qbytearray公司 )是吗?

    2 回复  |  直到 7 年前
        1
  •  6
  •   Barry    7 年前

    等价物 ~ C++中的功能将是:

    auto func(optional<QByteArray>&& o) -> QByteArray
    {
        return std::move(o).value();
    }
    

    std::move(o) 给你一个 optional<QByteArray> 是的。调用 value() 在这个值上给你一个 QByteArray&& (如果 o 断开连接)。那种价值观 QByteArray 用于移动构造返回对象。这种移动构造很便宜,只需要几个指针分配—不进行内存分配。


    ~ 几乎相等。请注意 O型 这里有 最终成为一个脱离的人 optional 不同于铁锈。它还没订婚,只是拿着一个空的 Qbytearray公司 是的。如果真的需要,真正的等价物是:

    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
    }
    
        2
  •  6
  •   PaulR    7 年前

    你的假设 std::move 是错误的。粗略地说,std::move强制转换为rvalue引用,它本身不会生成任何实际代码。下一行将创建 QByteArray 在堆栈上调用其移动构造函数。

    QByteArray optarr = std::move(*myopt);
    

    move构造函数初始化 Data 另一个qbytearray的指针,并用指向共享空数据的指针替换另一个qbytearray的数据指针。不 malloc 涉及到,只有两个指针分配。

    这个 implementation 移动构造函数的类型如下:

    inline QByteArray(QByteArray && other) Q_DECL_NOTHROW : d(other.d) { other.d = Data::sharedNull(); }
    

    所以你的代码实际上是在做你想做的事情。