在联合体中使用 std::string 和 int

问题描述 投票:0回答:1

在同一联合内使用

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++ 标准角度来看,它是正确的代码吗?

c++ struct union undefined-behavior
1个回答
1
投票

您不应该将

union
与非平凡类型一起使用。
联合并不意味着处理其中 C++ 对象的正确构造和析构。

您在代码中手动处理了它,这在技术上是正确的,但很容易出错。如果你在联盟中建造或破坏了错误的类型,你很容易进入UB土地。

一般来说,在 C++ 中,建议使用

std::variant
作为通用求和类型。

因此,我建议使用以下内容代替您的工会:

std::variant<int, std::string> m_value;

这样你的

Foo
构造函数和析构函数就可以被
default
编辑。该变体将负责
std::string
(或其中任何其他重要类型)的正确构造和销毁。

© www.soinside.com 2019 - 2024. All rights reserved.