2

I have the following code:

Foo a;
if (some_fairly_long_condition) {
   a = complicated_expression_to_make_foo_1();
} else {
   a = complicated_expression_to_make_foo_2();
}

I have two issues with this:

  1. a is a const and should be declared so
  2. the "empty" constructor, Foo() is called for no reason (maybe this is optimised away?)

One way to fix it is by using the ternary operator:

const Foo a = some_fairly_long_condition?
      complicated_expression_to_make_foo_1():
      complicated_expression_to_make_foo_2();

Is this good practice? How do you go about it?

  • 4
    It is a matter of opinion, and in my opinion, yes, this is a good example of conditional operator usage. – juanchopanza Jul 25 '16 at 06:40
  • 3
    Another option would be `const Foo a = compute_foo();` and put the complicated stuff in a separate function. Would make it reusable too. – Bo Persson Jul 25 '16 at 06:50
  • Some discussion on this subject before: http://stackoverflow.com/q/4192225/168175, from the other angle – Flexo Jul 25 '16 at 07:21

2 Answers2

3

To answer the second part of your question:
I usually put the initialization code into a lambda:

const Foo a = [&]()->Foo{
    if (some_fairly_long_condition) {
        return complicated_expression_to_make_foo_1();
    } else {
        return complicated_expression_to_make_foo_2();
    }
}();

In most cases you should even be able to omit the trailing return type, so you can write

const Foo a = [&](){ ...

As far as the first part is concerned:
I'd say that greatly depends on how complex your initialization code is. If all three parts are really complicated expressions (and not just a function call each) then the solution with the ternary operator becomes an unreadable mess, while the lambda method (or a separate named function for that matter) allows you to break up those parts into the respective sub expressions.

MikeMB
  • 20,029
  • 9
  • 57
  • 102
  • 3
    Sure, but part of the question is whether the conditional operator is a good way to go about this. And I think it is better than this lambda. – juanchopanza Jul 25 '16 at 06:38
  • @juanchopanza: As far as I'm concerned, that depends on whether `complicated_expression..` and `some_fairly_long_condition` are just placeholders for function names or actually complicated and long expressions. Sure, you can achieve a lot by *"proper"* formatting, but that often doesn't hold when automatic formatting is at play and in addition, the lambda version allows you to break up those statements into simpler sub-parts. – MikeMB Jul 25 '16 at 06:55
  • 1
    Agreed. My assumption is that the complicated expressions would be put into functions if they are more than a few tokens long. – juanchopanza Jul 25 '16 at 06:57
  • So, turns out my two expressions aren't the same type, so even the ternary operator doesn't end up working :/ –  Jul 25 '16 at 12:44
0

If the problem is to avoid ternaty operator and your goal is to define the constant a, this code is an option:

Foo aux;
if (some_fairly_long_condition) {
   aux = complicated_expression_to_make_foo_1();
} else {
   aux = complicated_expression_to_make_foo_2();
}
const Foo a(aux);

It is a good solution, without any new feature ---as lambdas--- and including the code inline, as you want.

EFenix
  • 831
  • 4
  • 11