diff --git a/include/tl/expected.hpp b/include/tl/expected.hpp index 2c852e6..7dd82b7 100644 --- a/include/tl/expected.hpp +++ b/include/tl/expected.hpp @@ -1680,19 +1680,20 @@ public: T, Args &&...>::value> * = nullptr> void emplace(Args &&... args) { if (has_value()) { - val() = T(std::forward(args)...); + val().~T(); } else { err().~unexpected(); - ::new (valptr()) T(std::forward(args)...); this->m_has_val = true; } + ::new (valptr()) T(std::forward(args)...); } template ::value> * = nullptr> void emplace(Args &&... args) { if (has_value()) { - val() = T(std::forward(args)...); + val().~T(); + ::new (valptr()) T(std::forward(args)...); } else { auto tmp = std::move(err()); err().~unexpected(); diff --git a/tests/issues.cpp b/tests/issues.cpp index e9f99da..276c401 100644 --- a/tests/issues.cpp +++ b/tests/issues.cpp @@ -136,3 +136,27 @@ tl::expected> func() TEST_CASE("Issue 61", "[issues.61]") { REQUIRE(func().value() == 1); } + +struct move_tracker { + int moved = 0; + + constexpr move_tracker() = default; + + constexpr move_tracker(move_tracker const &other) noexcept = default; + constexpr move_tracker(move_tracker &&orig) noexcept + : moved(orig.moved + 1) {} + + constexpr move_tracker & + operator=(move_tracker const &other) noexcept = default; + + constexpr move_tracker &operator=(move_tracker &&orig) noexcept { + moved = orig.moved + 1; + return *this; + } +}; + +TEST_CASE("Issue 122", "[issues.122]") { + tl::expected res; + res.emplace(); // why moved? + REQUIRE(res.value().moved == 0); +} \ No newline at end of file