【问题标题】:Creating constructor for the structure with union使用联合为结构创建构造函数
【发布时间】:2021-03-09 05:13:11
【问题描述】:

This我的问题很好地解决了这个问题。

但是,看起来我需要为该结构创建一个构造函数,因为以下代码:

std::vector<Foo> row;
row.push_back( Foo( 1, 1 ) );

出错了。

当我尝试添加构造函数时

Foo(int mytype, int myvalue)
{
    type = mytype;
    value.intvalue = myvalue;
}

说错了

attempting to reference a deleted function

我需要定义所有 3 个构造函数吗?

还是有别的?

TIA!!

【问题讨论】:

  • This 问题中,您没有接受任何答案。但是,answer with most votes 建议使用std::variant。这将使您对这些丑陋的union 的所有摆弄都过时了...union 是 C 的继承,并且不能很好地与 C++ 中的类一起使用。那么,为什么会有这么多麻烦呢?
  • @Scheff,std::variant 是 C++17。我还在使用 C++11。
  • 好的。我忽略了 [c++11] - 我的错。但是,即使这是一个后续问题,也请提供minimal reproducible example。您的 union 可能缺少一些重要的东西,我看不到什么(没有代码)。
  • boost(和其他 C++11 兼容库)具有变体类型。

标签: c++ c++11


【解决方案1】:

引用自this even older answer:

[class.union]/2 中的标准状态

联合可以具有成员函数(包括构造函数和析构函数),但不能具有虚拟 (10.3) 函数。联合不应有基类。联合不应用作基类。如果联合包含引用类型的非静态数据成员,则程序格式错误。最多一个联合的非静态数据成员可以有一个大括号或相等初始化器。 [ 注意:如果联合的任何非静态数据成员具有非平凡的默认构造函数 (12.1)、复制构造函数 (12.8)、移动构造函数 (12.8)、复制赋值运算符 (12.8)、移动赋值运算符 ( 12.8)或析构函数(12.4),联合的相应成员函数必须是用户提供的,否则它将为联合隐式删除(8.4.3)。 — 尾注 ]

强调我的

因此,OP 对析构函数所做的事情对于构造函数(也许还有赋值运算符)可能也是必要的。

这里是带有构造函数的 OP 增强示例:

#include <iostream>  
#include <string>

struct Value {
    int type;

    union Data {
        int intValue;
        double doubleValue;
        std::string stringValue;
        
        Data(int value): intValue(value) { }
        Data(double value): doubleValue(value) { }
        Data(const std::string &value): stringValue(value) { }
        ~Data() noexcept { }
    } data;

    Value(int value): type(1), data(value) { }
    
    Value(double value): type(2), data(value) { }

    Value(const std::string &value): type(3), data(value) { }
    
    ~Value()
    {
        using std::string;
        if (type == 3) data.stringValue.~string();
    }
};

int main()  
{
  { Value value(123);
    std::cout << "value: " << value.type << ": '" << value.data.intValue << "'\n";
  }
  { Value value(1.23);
    std::cout << "value: " << value.type << ": '" << value.data.doubleValue << "'\n";
  }
  { Value value(std::string("Hello world"));
    std::cout << "value: " << value.type << ": '" << value.data.stringValue << "'\n";
  }
}

输出:

value: 1: '123'
value: 2: '1.23'
value: 3: 'Hello world'

Live Demo on coliru

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多