std :: optional的值的地址是否稳定?

时间:2018-02-03 19:11:55

标签: c++ language-lawyer std c++17

说我有std::optional<T>。我重置并多次赋值。对于给定的可选项,值(如果存在)的地址是否始终相同?

换句话说:

#include <cassert>
#include <optional>
#include <string>

template<typename T>
auto test()
{
    auto opt = std::optional<T>{T{}};
    auto* ptr = &*opt;

    opt.reset();
    opt = T{};

    assert(ptr == &*opt); // Can this assert fail?
}

int main()
{
    test<int>();
    test<double>();
    test<std::string>();
    // ...
}

标准是否保证了值的地址的稳定性?

1 个答案:

答案 0 :(得分:13)

  

标准是否保证了值的地址的稳定性?

从我的角度来看,未指定地址是否稳定。

正式地,标准仅保证std::optional中包含的对象没有动态分配,并且包含对象存储为std::optional的一部分:

  

23.6.3类模板可选[optional.optional]

     

任何给定时间的任何可选实例都包含一个值   或者不包含值。 当一个可选实例包含时   一个值,它表示一个T类型的对象,简称为   可选对象的包含值,是在存储内分配的   可选对象。不允许使用实现   额外的存储,如动态内存,来分配其包含的内容   值。所包含的值应分配在该区域内   可选存储适合于类型T对齐。当一个对象时   type optional是从上下文转换为bool的转换   如果对象包含值,则返回true;否则转换   返回false。

实际存储机制由特定实现定义,因此,地址可能会发生变化。

但实际上,实现将使用aligned_storage(请参阅 boost implementation)或union(作为 gcc does)并保持包含对象的地址相同。