std::optional 成员是不是连续存储?

Posted

技术标签:

【中文标题】std::optional 成员是不是连续存储?【英文标题】:Are std::optional members stored contiguously?std::optional 成员是否连续存储? 【发布时间】:2021-08-27 13:42:44 【问题描述】:

我想我对如何存储可选值感到有些困惑。在构造包含std::optional<T> 成员的类或结构时,这些成员是连续存储在内存中还是可选动态分配?例如,下面的结构会是一个连续的内存块吗?

struct Material
    
        std::string name;
        std::optional<size_t> albedo;
        std::optional<size_t> normal;
        std::optional<size_t> metalness;
        std::optional<size_t> roughness;
        std::optional<size_t> ao; // ambient occlusion
        bool hasAlphaChannel = false;
    ;

【问题讨论】:

除了std::optional 内部存储之外,您仍然担心padding 可能会导致您的成员不连续。 【参考方案1】:

optional 要求不使用动态分配。

如果一个可选项包含一个值,则该值保证作为可选对象占用空间的一部分进行分配,即不会发生动态内存分配。因此,即使定义了 operator*() 和 operator->(),可选对象也建模对象,而不是指针。

https://en.cppreference.com/w/cpp/utility/optional

还有optional 的成员变量和可能发生的填充。所以不,它们不一定是连续的,但它们在您声明它们的对象内。

【讨论】:

【参考方案2】:

根据标准std::optional禁止为其直接成员使用动态内存。

一种可能的布局例如是:

template<class T>
class optional

    bool engaged;
    union 
        T value;
        unsigned char reserved;
    ;
;

【讨论】:

reserved 是不必要的 该名称在此上下文中不是可选的。 不需要名为reserved 的整个成员。 union T value; 有效。

以上是关于std::optional 成员是不是连续存储?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Xcode 中获得 std::optional 支持?

通过引用传递 std::optional<T> 是不是实际上保存复制?

C++ 标准是不是允许在没有开销的情况下实现 std::optional<double>

std::optional::value_or() - 惰性参数评估

std::optional

将一个 std::optional 转换为另一个 std::optional