为什么 LLVM 的 Optional<T> 是这样实现的?
Why is LLVM's Optional<T> implemented this way?
我偶然发现了 Optional<T>
的实现,它基于 LLVM 的 Optional.h class 并且无法完全弄清楚为什么它是这样实现的。
为了简短起见,我只粘贴了我不明白的部分:
template <typename T>
class Optional
{
private:
inline void* getstg() const { return const_cast<void*>(reinterpret_cast<const void*>(&_stg)); }
typedef typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type storage_type;
storage_type _stg;
bool _hasValue;
public:
Optional(const T &y) : _hasValue(true)
{
new (getstg()) T(y);
}
T* Get() { return reinterpret_cast<T*>(getstg()); }
}
我能想到的最天真的实现:
template <typename T>
class NaiveOptional
{
private:
T* _value;
bool _hasValue;
public:
NaiveOptional(const T &y) : _hasValue(true), _value(new T(y))
{
}
T* Get() { return _value; }
}
问题:
- 如何解释
storage_type
?作者的意图是什么?
- 这一行的语义是什么:
new (getstg()) T(y);
?
- 为什么天真的实现不起作用(或者,
Optional<T>
class 比 NaiveOptional<T>
有什么优点)?
Std::optional 应该从函数中返回。这意味着您必须将指针引用的内容存储在某处。这违背了 class
的目的
此外,您不能只使用纯 T,否则您将不得不以某种方式构造它。 Optional 允许内容不初始化,部分类型不能默认构造。
为了使 class 在支持的类型方面更加灵活,使用了合适且正确对齐的存储。并且仅当 optional 处于活动状态时,才会在其上构造真实类型
您的想法可能类似于 std::variant?
简短的回答是 "performance"。
更长的答案:
我偶然发现了 Optional<T>
的实现,它基于 LLVM 的 Optional.h class 并且无法完全弄清楚为什么它是这样实现的。
为了简短起见,我只粘贴了我不明白的部分:
template <typename T>
class Optional
{
private:
inline void* getstg() const { return const_cast<void*>(reinterpret_cast<const void*>(&_stg)); }
typedef typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type storage_type;
storage_type _stg;
bool _hasValue;
public:
Optional(const T &y) : _hasValue(true)
{
new (getstg()) T(y);
}
T* Get() { return reinterpret_cast<T*>(getstg()); }
}
我能想到的最天真的实现:
template <typename T>
class NaiveOptional
{
private:
T* _value;
bool _hasValue;
public:
NaiveOptional(const T &y) : _hasValue(true), _value(new T(y))
{
}
T* Get() { return _value; }
}
问题:
- 如何解释
storage_type
?作者的意图是什么? - 这一行的语义是什么:
new (getstg()) T(y);
? - 为什么天真的实现不起作用(或者,
Optional<T>
class 比NaiveOptional<T>
有什么优点)?
Std::optional 应该从函数中返回。这意味着您必须将指针引用的内容存储在某处。这违背了 class
的目的此外,您不能只使用纯 T,否则您将不得不以某种方式构造它。 Optional 允许内容不初始化,部分类型不能默认构造。
为了使 class 在支持的类型方面更加灵活,使用了合适且正确对齐的存储。并且仅当 optional 处于活动状态时,才会在其上构造真实类型
您的想法可能类似于 std::variant?
简短的回答是 "performance"。
更长的答案: