I am trying to learn std::variant
. I do not understand why in this example, where I prefer not to initialize ab
yet, and I use std::monostate
for that, the class A
gets constructed once, but destructed twice. What is happening?
#include <iostream>
#include <variant>
struct A
{
A() { std::cout << "Constructing A\n"; }
~A() { std::cout << "Destructing A\n"; }
};
struct B
{
B() { std::cout << "Constructing B\n"; }
~B() { std::cout << "Destructing B\n"; }
};
int main()
{
std::variant<std::monostate, A, B> ab;
ab = A();
}
Running this example gives the output below.
Constructing A
Destructing A
Destructing A
This line:
ab = A();
Is creating a temporary A
object, and then moving it into ab
.
You can observe this by adding copy/move constructors and assignment operators:
#include <iostream>
#include <variant>
struct A
{
A() { std::cout << "Constructing A\n"; }
A(A const&) { std::cout << "Copy constructing A\n"; }
A(A&&) { std::cout << "Move constructing A\n"; }
A& operator=(A const&) { std::cout << "Copy assigning A\n"; return *this; }
A& operator=(A&&) { std::cout << "Move assigning A\n"; return *this; }
~A() { std::cout << "Destructing A\n"; }
};
struct B
{
};
int main()
{
std::variant<std::monostate, A, B> ab;
ab = A();
}
Output:
Constructing A
Move constructing A
Destructing A
Destructing A
You can avoid the copy/move, by using std::variant::emplace
.
If you replace the above mentioned line with:
ab.emplace<A>();
The output should become:
Constructing A
Destructing A