Consider this code:
#include <variant>
struct x {
int y;
};
int main() {
std::variant<x> v(std::in_place_type<x>, {3}); /*1*/
return std::get<x>(v).y;
}
This does not compile and neither does when removing the {}
from the line /*1*/
, even though aggregate initialization
x a{3};
x b({3});
works in both "constructor-like" forms. Can I somehow make the std::variant
initializer aware of the possibility of constructing structs using aggregate initialization without having to write boring boilerplate constructors for each struct that may be used in my real-world case?
I would expect this to work, somehow, as per cppreference the two overloads (5) and (6) in question both say
Constructs a variant with the specified alternative T and initializes the contained value with the arguments [...]
I'm using GCC 7 if that matters.
There is no workaround for this, apart from adding a constructor. The standard mandates this for both overloads you mention, [variant.ctor]19 and [variant.ctor]23 respectively:
Effects: Initializes the contained value as if direct-non-list-initializing an object of type
T
with the argumentsstd::forward<Args>(args)...
.Effects: Initializes the contained value as if direct-non-list-initializing an object of type
T
with the argumentsil, std::forward<Args>(args)...
.
You can always copy or move the object using:
std::variant<x> v(std::in_place_type<x>, x{3});
// or more clear and does the same thing
std::variant<x> v(x{3});