有没有安全的方法可以推导出 std::optional中 T 的偏移量<T>?



给定一个std::optional<T>,是否可以从T的地址导出std::optional<T>的地址?

可能的实现:

template<typename T>
struct myoptional
{       static std::size_t getOffset(void)
{       static const myoptional<T> s(std::inplace());
return reinterpret_cast<const char*>(&s.value())
- reinterpret_cast<const char*>(&s);
};
};

未指定std::optional存储对象的确切位置。如果假设同一类型的T的对象位置始终相同,则可以(见下文(使用所示方法通过对象表示来获得偏移。

但是,即使知道对象的偏移量,仍然无法从指向T对象的指针中获得指向std::optional<T>的可用指针。您需要std::launder结果指针使其可用,只有在sizeof(std::optional<T>) <= sizeof(T)的情况下才允许使用,这似乎不太可能。(否则,它将使以前不可访问的字节达到术语可访问的含义,如std::launder的前提条件中所述,请参阅https://en.cppreference.com/w/cpp/utility/launder)


标准是否允许使用reinterpret_cast和指针运算目前尚不清楚。该标准在这方面存在一些尚未解决的缺陷。

不过,您也可以使用std::optional<T>unionunsigned char[sizeof(std::optional<T>)],而不是使用指针差,然后您可以在循环中使用加法和指针比较来查找字符数组中与T值的地址匹配的偏移量。例如看这个答案。

最新更新