'Unnamed union member has non-trivial operator
I am working on a project started back to 1980s, my mission is to substitute the primitive double with the Dummy class I create. The following is the simplified problematic code:
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;
}
And the following is the error message I got, when I compiled it with 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 ;
| ^~
However when I compiled the original project with g++ 9.3.0, only the problem on the line 41 is reported, which is the problem I want to solve.
I need the overloaded operator to enable copying fromm volatile instances to non-volatile ones for the project.
I have seen the solution here, which is to name the unnamed union and make it a tagged union, but the problem of this solution is that this struct is widely used, if I do it in this way, it will involve too many manual modifications.
I tried to overload operator "=" for the unnamed union with the following code, which doesn't work:
union {
Dummy dm ;
int i;
void* operator=(const Dummy& d){
this->dm = d;
return this;
};
}B;
How can I solve this problem? Thank you.
Solution 1:[1]
Not sure if those modifications are possible for you, but following compiles
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;
};
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Jarod42 |