Reputation: 93324
struct Something {
union {
float k;
int n;
};
bool isFloat;
bool operator==(const Something& mS)
{
if(isFloat != mS.isFloat) return false;
if(isFloat && mS.k == k) return true;
if(!isFloat && mS.n == n) return true;
}
};
My implementation of Something::operator==
seems rather expensive and convoluted. Is this the only way to check equality in classes with union types?
Or is there a better way that avoids branches/checking additional variables?
Upvotes: 3
Views: 124
Reputation: 254621
You can remove one redundant check, and perhaps enhance readability slightly, by replacing the last two lines with
if(isFloat != mS.isFloat) return false; // As you have
return isFloat ? mS.k == k : mS.n == n;
(or the equivalent if
construct, as in Sean Perry's answer) but the compiler will probably do just as good a job of optimising your version.
There's no way to avoid a runtime check that the types match. You might consider a ready-made discriminated union type like Boost.Variant; it won't be any more efficient, but it might be easier and less error-prone to use.
Upvotes: 1
Reputation: 311048
I do not think that you can escape checking all the conditions. So the question can be how to write them more simpler and expressively.
I would write them the following way
bool operator==( const Something &mS ) const
{
return ( ( isFloat == mS.isFloat ) && ( isFloat ? k == mS.k : n == mS.n ) );
}
Upvotes: 0
Reputation: 3886
bool operator==(const Something& mS)
{
if (isFloat != mS.isFloat)
{
return false;
}
else if (isFloat)
{
return mS.k == k;
}
else
{
return mS.n == n;
}
}
Clear and debuggable with the minimum number of checks. You want to have a constructor and/or set methods to ensure isFloat is correct at all times.
Upvotes: 3
Reputation: 23058
return (isFloat && mS.isFloat && k==mS.k) || (!isFloat && !mS.isFloat && n==mS.n);
Upvotes: 0