【问题标题】:Referencing deleted destructor引用已删除的析构函数
【发布时间】:2021-03-05 03:42:39
【问题描述】:

我有以下代码:

struct Foo
{
    int type;
    union
    {
        int intValue;
        double doubleValue;
        std::wstring stringValue;
    } value;
};

然后在我的 cpp 文件中:

std::vector<Foo> row;
some_class_object->func( row );

我得到了:

error C2280: 'void *Foo::__delDtor(unsigned int)': attempting to reference a deleted function 

这里有什么问题?

编辑:

所以我添加了这个析构函数:

~Foo()
{
    if( type ==3 )
        value.stringValue.~std::wstring();
}

我得到一个错误:

error C2061: syntax error: identifier 'wstring'.

在这种情况下,显然 std::string 与 std::wstring 很重要......

不知道。

EDIT2:

我现在得到:

 error C2280: 'Foo::<unnamed-type-value>::~<unnamed-type-value>(void)': attempting to reference a deleted function

【问题讨论】:

  • 使用union只实现variant,然后使用它。 Boost 为 pre-C++17 提供了一个,std 从 C++17 开始提供。

标签: c++ c++11


【解决方案1】:

联合包含一个具有重要析构函数的成员 (std::string)。这意味着联合不能有默认的析构函数(它不知道要调用哪个成员的析构函数)。所以你需要提供一个自定义析构函数。

在您的情况下,定义一个什么都不做的联合析构函数,然后在结构析构函数中完成工作:

struct Foo {
    int type;

    union U {
        int intValue;
        double doubleValue;
        std::wstring stringValue;

        
        ~U() noexcept {}

    } value;

    ~Foo()
    {
        using std::wstring;

        if (type == 3)
            value.stringValue.~wstring();
    }
};

请注意,您也需要为复制/移动构造函数/赋值执行此操作。

在 C++17 中,std::variant 是一个安全联合。

【讨论】:

  • 那我该怎么写呢?我没有使用指针,只是一个普通的成员。而且我还没有 - 我没有跨平台的 C++17 编译器......
  • @Igor "那我该怎么写?" - 见Is a Union Member's Destructor Called
  • @RemyLebeau,我用我尝试过的代码和我得到的错误更新了 OP。
  • @Igor 删除std::,它不是析构函数名称的一部分:value.stringValue.~wstring(); 只要确保你事先使用过new(&amp;value.stringValue) wstring();
  • @Igor using std::wstring; value.stringValue.~wstring();
【解决方案2】:

UNION 已删除析构函数,您正试图将其用作匿名实体。你不能在没有命名类型的情况下定义析构函数。

struct Foo
{
    int type;
    union ValueType
    {
        int intValue;
        double doubleValue;
        std::wstring stringValue;
        ~ValueType() {}
    } value;
    ~Foo();
};

Foo::~Foo()
{
    if( type ==3 )
        value.stringValue.std::wstring::~wstring();
}

最好使用编译器提供的标准标记联合模板,而不是滚动你自己的模板,因为这样晦涩难懂的代码。

【讨论】:

  • 什么是联合模板?能否提供代码示例或链接文档?
猜你喜欢
  • 2013-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-06
  • 2012-03-13
  • 2014-06-29
  • 2012-08-11
  • 2022-01-22
相关资源
最近更新 更多