在同一联合内使用
std::string
(或其他非平凡类型)与 int
(或其他平凡和非平凡类型)是否正确?
我已经这样实现了:
#include <iostream>
#include <string>
struct Foo
{
enum Type {data_string, data_int};
int m_type;
Foo(Type t) : m_type(t)
{
if (t == Type::data_string) {
new (&s) std::string();
}
}
~Foo()
{
if (m_type == Type::data_string) {
s.~basic_string();
}
}
union
{
int n;
std::string s;
};
};
int main()
{
Foo f1(Foo::Type::data_string);
f1.s = "hello ";
std::cout << f1.s;
Foo f2(Foo::Type::data_int);
f2.n = 100;
std::cout << f2.n;
}
而且效果非常好。但我不确定这段代码。从 C++ 标准角度来看,它是正确的代码吗?
您不应该将
union
与非平凡类型一起使用。您在代码中手动处理了它,这在技术上是正确的,但很容易出错。如果你在联盟中建造或破坏了错误的类型,你很容易进入UB土地。
std::variant
作为通用求和类型。
因此,我建议使用以下内容代替您的工会:
std::variant<int, std::string> m_value;
这样你的
Foo
构造函数和析构函数就可以被 default
编辑。该变体将负责 std::string
(或其中任何其他重要类型)的正确构造和销毁。