【问题标题】:Does it make sense to combine optional with reference_wrapper?将 optional 与 reference_wrapper 结合起来有意义吗?
【发布时间】:2018-07-21 03:18:24
【问题描述】:

我突然想到在 C++ 中可以使用 std::optional<std::reference_wrapper<T>> 类型。这种类型的对象本质上是对T 类型对象或空值的引用,即几乎是一个指针。我的问题:

  1. std::optional<std::reference_wrapper<T>>T* 之间在概念上有什么区别吗?

  2. 有什么实际区别吗?在某些情况下,建议选择std::optional<std::reference_wrapper<T>> 而不是T*

【问题讨论】:

  • 是的,这是有道理的。没有optional<T&>,所以optional< reference_wrapper<T> > 是我们拥有的最接近的。这传达了非所有权,没有未初始化的值,没有来自nullptr 的意外构造,没有意外算术,没有*-> 和 co 的丑陋。 (尽管由于在循环时必须避开 auto 导致一些 other 丑陋,但如果上下文不提供所需的转换等,请使用 .get())。这些都是对语义和安全性的具体好处。只是optional<T&> 会更简洁,但是我们会想知道为什么我们可以将它放在容器中而不是T&....

标签: c++ pointers reference optional c++-standard-library


【解决方案1】:

std::optional<std::reference_wrapper<T>>T* 之间在概念上有什么区别吗?

std::optional<>,顾名思义,是在我们可以有值或根本没有值时使用的。

对于T* 对象没有值 的等价物将分配nullptr 给它,即:指针将指向nowhere,而不是somewhere(甚至anywhere,即:未初始化)。可以说std::optional<> 导出了nullptr 的概念,用于指向任意类型的指针。所以,我想说它们在概念上非常相似,因为 std::option<> 方法是一种概括。

有什么实际区别吗?在某些情况下,建议选择std::optional<std::reference_wrapper<T>> 而不是T*

我能想到尺寸。 std::optional<> 包含一个内部标志,用于指示值的存在/不存在,而对于T*nullptr 直接编码为指针可以存储的值之一。所以std::optional<std::reference_wrapper<T>> 对象将大于T*

在安全性方面,与T* 不同,std::optional<> 提供了成员函数value(),如果没有值则抛出异常(它提供不安全的operator*()T* 一样) .

此外,例如,使用 std::optional<std::reference_wrapper<T>> 代替 T* 作为函数的返回值可能以更明确的方式表明可能根本没有任何值。

【讨论】:

    【解决方案2】:

    std::optional<std::reference_wrapper<T>>T* 之间的主要区别在于,对于T*,您必须考虑谁拥有所指向的内存。

    如果一个函数返回T*,你必须知道是你负责释放内存还是其他人负责。当它是参考时,您不必担心这一点。

    【讨论】:

    • 除非您与一些纯 c 库进行交互,否则堆内存几乎总是由 unique_ptrshared_ptr 拥有,或者像 vector 这样的某种池或容器。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-14
    • 1970-01-01
    • 1970-01-01
    • 2021-09-28
    • 1970-01-01
    • 2021-09-19
    • 2019-03-31
    相关资源
    最近更新 更多