According to the C++23 standard, what is the output of this program?
#include <iostream>
#include <variant>
struct C
{
C() : i(1){}
int i;
};
struct D
{
D() : i(2){}
int i;
};
int main()
{
const std::variant<C,D> v;
std::visit([](const auto& val){ std::cout << val.i; }, v);
}std::variants default constructor constructs a variant holding the value-initialized value of the first alternative.
1
What does the std::variant default constructor do? Which of the types does it pick, or is the variant empty? And if it picks one, how is the value initialized?
std::variants default constructor constructs a variant holding the value-initialized value of the first alternative. So it picks C as the type and calls the C::C() default constructor initializing it with i == 1, which gets printed.
In the descriptions that follow, let i be in the range
[0, sizeof...(Types)), andTi be the ith type inTypes.constexpr variant() noexcept(see below);(...)
Effects: Constructs a
variantholding a value-initialized value of type T0.
Now what does value-initialized mean?
To value-initialize an object of type
Tmeans:(...)
— if
Thas either no default constructor (§[class.default.ctor]) or a default constructor that is user-provided or deleted, then the object is default-initialized;
C has a user-provided constructor, so it's default-initialized. Now what does default-initialized mean?
To default-initialize an object of type
Tmeans:
— If
Tis a (possibly cv-qualified) class type (§[class]), constructors are considered. The applicable constructors are enumerated (§[over.match.ctor]), and the best one for the initializer()is chosen through overload resolution (§[over.match]). The constructor thus selected is called, with an empty argument list, to initialize the object.
There's only one default constructor, it gets called and initializes the C object with i == 1.