diff --git a/tests/issues.cpp b/tests/issues.cpp index 8636373..b271140 100644 --- a/tests/issues.cpp +++ b/tests/issues.cpp @@ -100,4 +100,9 @@ struct non_copyable { TEST_CASE("Issue 42", "[issues.42]") { tl::expected{}.map([](non_copyable) {}); +} + +TEST_CASE("Issue 43", "[issues.43]") { + auto result = tl::expected{}; + result = tl::make_unexpected(std::string{ "foo" }); } \ No newline at end of file diff --git a/tl/expected.hpp b/tl/expected.hpp index 8e8bc6e..740c6ad 100644 --- a/tl/expected.hpp +++ b/tl/expected.hpp @@ -732,7 +732,7 @@ struct expected_operations_base : expected_storage_base { if (rhs.m_has_val) { get() = std::forward(rhs).get(); } else { - get().~T(); + destroy_val(); construct_error(std::forward(rhs).geterr()); } } else { @@ -763,6 +763,10 @@ struct expected_operations_base : expected_storage_base { return std::move(this->m_unexpect); } #endif + + constexpr void destroy_val() { + get().~T(); + } }; // This base class provides some handy member functions which can be used in @@ -814,6 +818,10 @@ struct expected_operations_base : expected_storage_base { return std::move(this->m_unexpect); } #endif + + constexpr void destroy_val() { + //no-op + } }; // This class manages conditionally having a trivial copy constructor @@ -1655,7 +1663,7 @@ public: if (!has_value()) { err() = rhs; } else { - val().~T(); + this->destroy_val(); ::new (errptr()) unexpected(rhs); this->m_has_val = false; } @@ -1670,7 +1678,7 @@ public: if (!has_value()) { err() = std::move(rhs); } else { - val().~T(); + this->destroy_val(); ::new (errptr()) unexpected(std::move(rhs)); this->m_has_val = false; }