未命名的联合成员具有非平凡的运算符

Unnamed union member has non-trivial operator

我正在从事一个可以追溯到 80 年代的项目,我的任务是用我创建的 Dummy class 替换原始替身。以下是简化后有问题的代码:

class Dummy{
private:
    double d;
public:
    Dummy(){};
    Dummy(double d1): d{d1}{}; 
    Dummy& operator = ( const Dummy& dm ) {
        d = dm.d;
        return *this;
    }
    Dummy& operator = ( const volatile Dummy& dm ) {
        d = dm.d;
        return *this;
    }
};

struct A{
    bool isDummy;
    union{
        Dummy dm ;
        int i; 
    }B;
};

int main(){
    struct A a1;
    a1.B= 1.1;
    struct A a2;
    a2.B = a1.B;
    return 0;
}

下面是我用 x86-64 gcc 11.2 编译时得到的错误信息:

<source>: In function 'int main()':
<source>:38:14: error: use of deleted function 'A::A()'
   38 |     struct A a1;
      |              ^~
<source>:17:8: note: 'A::A()' is implicitly deleted because the default definition would be ill-formed:
   17 | struct A{
      |        ^
<source>:17:8: error: use of deleted function 'A::<unnamed union>::<constructor>()'
<source>:19:10: note: 'A::<unnamed union>::<constructor>()' is implicitly deleted because the default definition would be ill-formed:
   19 |     union{
      |          ^
<source>:20:15: error: union member 'A::<unnamed union>::dm' with non-trivial 'Dummy::Dummy()'
   20 |         Dummy dm ;
      |               ^~
<source>:40:14: error: use of deleted function 'A::A()'
   40 |     struct A a2;
      |              ^~
<source>:41:15: error: use of deleted function 'A::<unnamed union>& A::<unnamed union>::operator=(const A::<unnamed union>&)'
   41 |     a2.B = a1.B;
      |               ^
<source>:19:10: note: 'A::<unnamed union>& A::<unnamed union>::operator=(const A::<unnamed union>&)' is implicitly deleted because the default definition would be ill-formed:
   19 |     union{
      |          ^
<source>:20:15: error: union member 'A::<unnamed union>::dm' with non-trivial 'Dummy& Dummy::operator=(const Dummy&)'
   20 |         Dummy dm ;
      |               ^~

但是我用g++9.3.0编译原项目时,只报第41行的问题,这就是我要解决的问题

我需要重载运算符来为项目启用从易失性实例到非易失性实例的复制。

我看到了解决方法,就是给unnamed union命名,使之成为tagged union,但是这个解决方法的问题是这个struct被广泛使用,如果我在这个方式,它会涉及太多的手动修改。

我尝试使用以下代码为未命名的联合重载运算符“=”,但它不起作用:

union {
    Dummy dm ;
    int i; 
    void* operator=(const Dummy& d){
        this->dm = d;
        return this;
    };
}B;

我该如何解决这个问题?谢谢。

不确定这些修改是否适合您,但编译后

class Dummy
{
private:
    double d;
public:
    Dummy() = default;
    Dummy(double d1): d{d1}{}
    Dummy& operator = ( const Dummy& dm ) = default;
};

struct A{
    bool isDummy = true;
    union{
        Dummy dm;
        int i;

        decltype(auto) operator=(double d) { dm = d; return *this; }
    }B;

};

Demo