diff --git a/optional.hpp b/optional.hpp index 3ff6e69..ed7f8d1 100644 --- a/optional.hpp +++ b/optional.hpp @@ -242,8 +242,21 @@ class optional : private detail::optional_base { template optional& operator=(U&&); template optional& operator=(const optional&); template optional& operator=(optional&&); - template T& emplace(Args&&...); - template T& emplace(initializer_list, Args&&...); + + template T& emplace(Args&&...) { + static_assert(std::is_constructible::value, + "T must be constructible with Args"); + + *this = nullopt; + new (std::addressof(m_storage.t)) T(std​::​forward(args)...); + } + + template + tl::enable_if_t&, Args&&...>::value, T&> + T& emplace(initializer_list, Args&&...) { + *this = nullopt; + new (std::addressof(m_storage.t)) T(il, std​::​forward(args)...); + } // [optional.swap], swap void swap(optional& rhs) @@ -260,7 +273,7 @@ class optional : private detail::optional_base { } } else if (rhs.has_value()) { - new (&m_storage.t) T (std::move(rhs.m_storage.t)); + new (std::addressof(m_storage.t)) T (std::move(rhs.m_storage.t)); rhs.m_storage.t.T::~T(); } }