2016-06-18 16 views
2

私はstd::optionalを実装するために、実際にはconstexprをサポートしています。これを実装しようとしている私は解決することができていないこの問題の一つに着いたときconstexpr std ::任意の実装可能

constexpr optional<int> x(123); 
int arr[*x]; 

::optional<T>オブジェクトの内部では、私は値を格納するstd::aligned_storage_t<sizeof (T), alignof (T)>オブジェクトを使用して、使用法は次のようになりますoptional<T>のコンストラクタに新しい配置を使用して、値をストレージに組み込みます。

constexpr optional(const T& value) 
    noexcept(std::is_nothrow_copy_constructible<T>::value) 
    : ... 
{ 
    new (ptr_to_storage) T(value); // this breaks `constexpr` 
} 

は、他にどのように私はこれを実装することができます。しかし、新しい配置がconstexprコンストラクタの内部で使用することはできませんか?

答えて

1

ユニオンを使用できます。

はアンジェイはそれをしない方法をチェックアウト:

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() {} 
}; 


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(); } 
}; 
+0

うわー、それは本当に私が今までに予想されるだろうとずっと多くのコードです。 –

+6

@ZizhengTaiようこそC++へ – James

+3

@jamesようこそ、C++に近い言語レベルの機能を実装することを歓迎します。 ;) – Yakk

関連する問題