mpark / variant

C++17 `std::variant` for C++11/14/17
https://mpark.github.io/variant
Boost Software License 1.0
659 stars 88 forks source link

Rarer `valueless_by_exception` #25

Closed mpark closed 6 years ago

mpark commented 7 years ago

Implement section III of P0308 as a non-standard version (outside of cpp17 namespace).

Types such as variant<int, double> should not ever get into a valueless_by_exception state. Something like:

template <std::size_t I, typename... Args>
inline auto &emplace(Args &&... args) {
  using T = variants::lib::type_pack_element_t<I, Ts...>;
  if constexpr (std::is_nothrow_constructible_v<T, Args...> ||
                !std::is_nothrow_move_constructible_v<T>) {
    this->destroy();
    auto &result = this->construct_alt(access::base::get_alt<I>(*this),
                                       std::forward<Args>(args)...);
    this->index_ = I;
    return result;
  } else {
    T temp(std::forward<Args>(args)...);
    this->destroy();
    auto &result = this->construct_alt(access::base::get_alt<I>(*this), std::move(temp));
    this->index_ = I;
    return result;
  }
}
viboes commented 7 years ago

+1 If I had a variant that can ensure the non-empty guaranties I would try to implement std::expected wrapping a stdxx::variant.

Note that std::expected could ensure the non-empty guaranties as the type E must be nothrow as used to report errors.

mpark commented 7 years ago

It's not clear to me how this ticket would help with the implementation of expected. Even if E is required to be nothrow move, T doesn't have that requirement right? So it seems to me like it wouldn't help in the general case? or does expected have optional-like behavior where it falls back to the default-constructed error state or something?

viboes commented 7 years ago

Hrr, maybe you are right and I was thinking on P0110R0. No, neither std::expected nor std::optional fallbacks, at least I don't remember of that.