constexpr std ::可选的可能实现
constexpr std::optional possible implementation
我正在尝试以constexpr
支持作为练习来实现std::optional
。用法将是:
constexpr optional<int> x(123);
int arr[*x];
尝试实施此功能时,我得到了一个我无法解决的问题:在optional<T>
对象中,我使用std::aligned_storage_t<sizeof (T), alignof (T)>
对象存储该值,并在optional<T>
的构造器中使用新的位置来构造值进入存储。但是新的位置不能在constexpr
构造函数中使用:
constexpr optional(const T& value)
noexcept(std::is_nothrow_copy_constructible<T>::value)
: ...
{
new (ptr_to_storage) T(value); // this breaks `constexpr`
}
我还能如何实现?
您可以使用联合。
查看Andrzej的工作方式:
https://github.com/akrzemi1/optional/blob/master/optional.hpp#l282
template <class T>
union storage_t
{
unsigned char dummy_;
T value_;
constexpr storage_t( trivial_init_t ) noexcept : dummy_() {};
template <class... Args>
constexpr storage_t( Args&&... args ) : value_(constexpr_forward<Args>(args)...) {}
~storage_t() = default;
};
template <class T>
struct optional_base
{
bool init_;
storage_t<T> storage_;
constexpr optional_base() noexcept : init_(false), storage_(trivial_init) {};
explicit constexpr optional_base(const T& v) : init_(true), storage_(v) {}
explicit constexpr optional_base(T&& v) : init_(true), storage_(constexpr_move(v)) {}
template <class... Args> explicit optional_base(in_place_t, Args&&... args)
: init_(true), storage_(constexpr_forward<Args>(args)...) {}
template <class U, class... Args, TR2_OPTIONAL_REQUIRES(is_constructible<T, std::initializer_list<U>>)>
explicit optional_base(in_place_t, std::initializer_list<U> il, Args&&... args)
: init_(true), storage_(il, std::forward<Args>(args)...) {}
~optional_base() { if (init_) storage_.value_.T::~T(); }
};
注意:
如果要获得一个支持在constexpr
函数中的局部变量中使用的答案,并且在运行时将其与不可损害的值一起使用,则该解决方案存在一些复杂性。(可能,您确实想支持此,您不希望您的constexpr optional
泄漏,或者不是常规可选的替换。)
这是因为必须根据语言规则默认constexpr
破坏者,但是在某些情况下必须调用通用参数的destructor。
在Andrzej的示例中,通过使用SFINAE并打开std::is_trivially_destructible
来解决此问题,以切换到optional_base
类的两个不同的实现,一个是带有默认破坏者的,一个没有。我在上面的清单中省略了这一点。如果您想要所有的血腥细节,我建议您阅读Andrzej的代码。
相关文章:
- 如果没有malloc,链表实现将失败
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 如何在c++中实现处理器调度模拟器
- 如何在c++中使用引用实现类似python的行为
- 实现无开销push_back的最佳方法是什么
- 多成员Constexpr结构初始化
- 条件constexpr函数
- 使用简单类型列表实现的指数编译时间.为什么
- constexpr 函数中的非文字(通过 std::is_constant_evaluated)
- Visual C++ constexpr Hints
- 如何在BST的这个简单递归实现中消除警告
- 如何确认我的constexpr表达式实际上已经在编译时执行
- C++constexpr实现差异
- 如何在 constexpr 函数中实现回退运行时
- constexpr std ::可选的可能实现
- std::experimental::可选<T>实现:Constexpr 构造函数混淆
- C++11 constexpr 字符串实现
- Constexpr查找实现
- 静态constexpr方法实现导致GCC错误
- C++11 constexpr兼容性实现