Rum*_*rak 17 c++ std language-lawyer 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>();
// ...
}
Run Code Online (Sandbox Code Playgroud)
标准是否保证了值的地址的稳定性?
Edg*_*jān 13
标准是否保证了值的地址的稳定性?
从我的观点来看,未指明地址是否稳定.
在形式上,标准仅保证对于包含在std::optional其中的对象没有动态分配,并且包含对象存储为以下部分的一部分std::optional:
23.6.3类模板可选[optional.optional]
任何给定时间的任何可选实例都包含值或不包含值.当可选实例包含值时,意味着在可选对象的存储中分配类型为T的对象(称为可选对象的包含值).不允许实现使用额外的存储(例如动态内存)来分配其包含的值.包含的值应分配在可选存储区域中,适合于类型T对齐.当可选类型的对象在上下文中转换为bool时,如果对象包含值,则转换返回true; 否则转换返回false.
实际存储机制由特定实现定义,因此,地址可能会发生变化.
然而,在实践中,实现将使用类似aligned_storage(参见boost 实现)或union(如gcc 所做的)并保持包含对象的地址相同.