One liner for operation with two different operators

57 Views Asked by At

I have a bitflag enum EFlags. Given a condition I want to either remove a flag or add a flag. I have defined the operator |= to add a flag and &= to remove a flag. For example, let us say the condition is bool b_condition:

EFlags flags;
bool b_condition = true;

if(b_condition)
  flags |= EFlags::FLAG;
else
  flags &= EFlags::FLAG;

I can easily convert this into a one liner with the following:

b_condition ? (flags |= EFlags::FLAG) : (flags &= EFlags::FLAG);

I am wondering if there is a way to have flags on one side and EFlags::FLAG on the other. That is, only the operator is affected by the terneary:

flags (b_condition ? |= : &=) EFlags::FLAG;

This code is incorrect. It does not work. How can I do something like this?

My reasoning: I have a line of these (18 currently) and I believe it will help massively with readability as currently it looks rather cluttered and it is a bit difficult to analyze. Also, I would not like a function like add_or_remove_flag_conditionally(EFlags& flag, EFlag modification_flag, bool b_add); Where it removes if b_add == false. This is my current approach, but I prefer to see the code, not an abstraction.

As requested: minimum reproducible example

enum EFlags : uint8_t
{
    NONE    =  0,
    FLAG    =  1,
    FLAG1   =  2,
    FLAG2   =  4,
};
    
void operator|=(EFlags& a, EFlags b)
{
    a = (EFlags)(a | b);
}

void operator&=(EFlags& a, EFlags b)
{
    a = (EFlags)(a & ~b);
}

int main()
{
    EFlags flags = NONE;
    const bool b_condition = true;
    b_condition ? (flags |= EFlags::FLAG) : (flags &= EFlags::FLAG);
    return 0;
}
1

There are 1 best solutions below

2
463035818_is_not_an_ai On

|= and &= are no objects that you can use as operands for the conditional operator. Though, operator|= and operator&= are:

 (b_condition ? (operator|=) : (operator&=))(flags,EFlags::FLAG);

Whether this is more readable is subjective of course. Just be prepared to some resistance during code reviews. Note that the conditional operator is actually not just a drop-in replacement for an if-else but there are things that can be expressed with the conditional operator that cannot be expressed with an if-else. This isnt one of them.