Search code examples
c++std-variant

Observing the state of a variant during construction


Consider the following code:

#include <variant>
#include <cassert>

struct foo {
  foo() noexcept;
  foo(const foo&) noexcept = default;
  foo(foo&&) noexcept = default;
  foo& operator=(const foo&) noexcept = default;
  foo& operator=(foo&&) noexcept = default;
};

std::variant<std::monostate, foo> var;  

foo::foo() noexcept {
    assert(!var.valueless_by_exception());
};

int main() {
    var.emplace<foo>();
}

With libstdc++ (from GCC 11), this works, but with libc++ (from LLVM 12), and MSVC, the assert fails.

Which standard library implements the correct behaviour ? At no point any exception is thrown, and my type is entirely noexcept, so I'd expect "valueless_from_exception" to never be true.

To quote the standard (https://timsong-cpp.github.io/cppwp/n4861/variant#status):

A variant might not hold a value if an exception is thrown during a type-changing assignment or emplacement.

here I am clearly not in that case.


Solution

  • The standard doesn't currently provide an answer to your question, but the direction that LWG appears to be moving in is that your code will have undefined behaviour.