以下基本代码是一个非常大的过程的一部分:
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标准,因为它属于跨平台项目。
我知道这可能是基于意见的,但考虑到先前关于简单性(不是混乱的代码)和避免时间变量(不是为了可读性而是为了代码安全性)的陈述,我想知道解决这个问题的选项
答案 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更清晰。