我正在尝试学习标准::变体
。我不明白为什么在这个例子中,我不想初始化 ab
,我为此使用 std::monostate
,类 A
被构造一次,但被破坏了两次。发生了什么事情?
#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();
}
运行此示例会给出以下输出。
Constructing A
Destructing A
Destructing A
此行:
ab = A();
正在创建一个临时A
对象,然后将其移动到ab
。
您可以通过添加复制/移动构造函数和赋值操作符来观察到这一点:
#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 assignment A\n"; return *this; }
A& operator=(A&&) { std::cout << "Move assignment A\n"; return *this; }
~A() { std::cout << "Destructing A\n"; }
};
struct B
{
};
int main()
{
std::variant<std::monostate, A, B> ab;
ab = A();
}
输出:
Constructing A
Move constructing A
Destructing A
Destructing A
您可以通过使用<code>std::variant::template</code>来避免复制/移动
如果您将上述行替换为:
ab.emplace<A>();
输出应变为:
Constructing A
Destructing A
我在你的代码中添加了2行。
struct A
{
A() { std::cout << "Constructing A\n"; }
A(const A& a) { std::cout << "Copy constructing A\n"; } // <== here
~A() { std::cout << "Destructing A\n"; }
};
struct B
{
B() { std::cout << "Constructing B\n"; }
B(const B& a) { std::cout << "Copy constructing B\n"; } // <== and here
~B() { std::cout << "Destructing B\n"; }
};
那么我们可以得到这样的结果:
Constructing A
Copy constructing A
Destructing A
Destructing A
我不熟悉std::variant,我只是希望上面的实验能让你更接近真实的答案。:)