const变量的条件初始化

时间:2017-04-24 10:35:17

标签: c++ c++11 initialization const

以下基本代码是一个非常大的过程的一部分:

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

x在其他任何地方都没有修改,所以我可以这样做:

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

但是foo()是一个非常昂贵和复杂的功能,所以我不能因为性能而调用它两次,并且因为它可能会产生竞争条件并因此获得不同的值(它可能涉及阅读)外部资源)。

我希望代码尽可能简单易读,如果可能,请尽量缩短。一种选择是:

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

另一方面,我希望避免使用这种时态变量,主要是因为foo()可能依赖于外部资源,因此在其余部分使用foo_作为缓存值代码无效。

我发布了我现在正在使用的解决方案,但我想知道是否有更好的选择(没有或几个代码混乱,同一范围内没有时间变量,可读性。 ..)。提前谢谢!

PS:它必须遵循至少C ++ 11标准,因为它属于跨平台项目。

我知道这可能是基于意见的,但考虑到先前关于简单性(不是混乱的代码)和避免时间变量(不是为了可读性而是为了代码安全性)的陈述,我想知道解决这个问题的选项

6 个答案:

答案 0 :(得分:6)

如果您乐意使用gcc extensions,那么您可以写下:

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

答案 1 :(得分:4)

我到目前为止找到的解决方案是使用lambda函数,例如:

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

答案 2 :(得分:3)

如何简单:

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

答案 3 :(得分:3)

基本上,你需要Elvis operator,但C ++没有。这是可能想要第二次使用的东西。因此,我选择了一般解决方案,而不是您提出的lambda解决方案。

例如

#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());

答案 4 :(得分:2)

除了lambda之外,如果你的程序中没有多次出现这种情况,你可以用函数包装函数foo(),让我们说conditionalFoo()

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

答案 5 :(得分:1)

由于这是基于意见的问题,我会选择:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup>
            <VisualState x:Name="Narrow">
                ...
            </VisualState>
            <VisualState x:Name="Wide">
                ...
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>

    <Grid>
        ...
    </Grid>
</Grid>

一个好名字而不是VisualStateManager甚至比仅仅尝试在没有命名的情况下使用lambdas更清晰。