Humam Helfawi
Humam Helfawi

Reputation: 20274

To not pass an argument due to a condition

I have this function declaration:

void do_somthing(int a,int b,foo bar = foo());

I want to call it for some arguments as follow:

foo bar = get_bar_by_some_algorithm();
int a = 5,b = 6;
if(bar.empty()){
    do_somthing(a,b);
}
else{
    do_somthing(a,b,bar);
}

I want to get rid of the if statement. So, I did it like this:

foo bar = get_bar_by_some_algorithm();
int a = 5,b = 6;
do_somthing(a,b,bar.empty()?foo():bar);

However, my approach is acceptable (is it good even?) if do_somthing is stable from default argument point of view but if it changed to something like this:

void do_somthing(int a,int b,foo bar = get_special_foo());

My code will be outdated because foo() is not equal too get_special_foo().

The question is How can I use ? operator or any short equivalent to pass an argument in case of non-empty and NOT Passing anything in case of empty?

Example for clarification (Imaginary syntax):

do_somthing(a,b,bar.empty()? the_default_argument : bar);

Upvotes: 2

Views: 148

Answers (2)

Peter
Peter

Reputation: 36607

The short answer is that you can't use ?: for this.

The specification of ?: ternary operator requires all three operands to be valid expressions. A valid expression (over-simplistically) is a construct that evaluates one or more values, (optionally) acts on the values using operators, and produces a result.

An expression with nothing in it is a contradiction: it doesn't evaluate anything, so cannot be an operand of the ?: operator.

Note: it is possible to have an empty statement (e.g. by having an isolated ;). But an empty statement is not an expression.

The obvious solution to hide the if() away would be to do the test inside your function, as mentioned in comments by CompuChip. Or write a wrapper function that does the test for you (and ensure that your do_somthing() is not declared in any other compilation unit, to avoid temptation of calling it directly rather than the wrapper).

Upvotes: 1

paddy
paddy

Reputation: 63471

Your approach with the ternary operator was okay, but seemed unnecessary. It's not normal to slap in new default values for functions at a later date without considering the consequences. If your default value is not meaningful, then something is wrong with your design in the first place.

But just to entertain you, here's a branchless version. I might consider something like this if my main concern was a measured bottleneck due to branch misprediction. I would not normally do this, because it's less clear than a simple if-statement:

static auto do_something[2] = {
    +[]( int a, int b, foo bar ) { do_something( a, b, bar ); },
    +[]( int a, int b, foo bar ) { do_something( a, b ); }
};
do_something[bar.empty()]( a, b, bar );

Upvotes: 2

Related Questions