Conditional initialization of a constant variable

The following base code is part of a fairly large procedure:

int x = foo();
if (x == 0) x = bar();

x doesn't change anywhere, so I could do:

const int x = foo() == 0 ? bar() : foo();

But it foo()’s a very expensive and complicated function, so I can’t name it twice because of the performance and the fact that it can generate a race condition and, therefore, get different values ​​(this may be due to reading external resources).

I would like to make the code as readable and as short as possible. One of the options:

const int foo_ = foo(), x = foo_ == 0 ? bar() : foo_;

On the other hand, I would like to avoid this temporary variable mainly because it foo()may depend on external resources, so the use of the foo_cached value in the rest of the code is invalid.

, , , ( , , ...). !

PS: , , ++ 11, - .

, , , ( ) ( , ), .

, , ( ):

static const auto fn_zero_conditional_init = []() {
  const int foo_ = foo();
  return foo_ ? foo_ : bar();
};
const int x = fn_zero_conditional_init();

, , . !

+4
6

, , :

auto get_the_correct_x=[](){
    const auto temp=foo();
    return temp==0?bar():temp;
}
const auto x=get_the_correct_x();

get_the_correct_x , lambdas .

+1

, , -, :

const int x = [](int n) { return n == 0 ? bar() : n; }(foo());
+4

gcc extensions, :

const int x = foo() ?: bar();
+4

:

const int temp_foo = foo();
const int x = (temp_foo == 0) ? bar() : temp_foo;
+3

, Elvis operator, ++ . , , , . - .

#include <functional>

int func_elvis (std::function<int ()> func1, std::function<int ()> func2) {
  int tmp = func1();
  return tmp ? tmp : func2();
}

const int x = func_elvis(foo, bar);

,

#define ELVIS(A, B) func_elvis([](){ return A; }, [](){ return B; })

const int x = ELVIS(foo(), bar());
+3

, , foo() , conditionalFoo():

int conditionalFoo() {
  int result = foo();
  if (result==0)
    result = bar();
  return result;
}
...
const int x = conditionalFoo();
+2

Source: https://habr.com/ru/post/1675508/


All Articles