C++中能否实现短路求值式指针赋值?求等效合法写法
实现C++短路逻辑的等效方案
当然有办法实现你想要的这种短路逻辑!先说说你原来的写法为什么编译失败:foo() || bar()会返回一个bool值(表示表达式是否为真),而你试图把这个bool直接赋值给int*类型的x,C++不允许这种隐式转换,所以编译器报错。
下面给你几种简洁且有效的等效实现,按推荐程度排序:
1. 短路赋值写法(最接近你的需求,无冗余调用)
这是最紧凑且符合短路逻辑的写法,利用||的短路求值特性,同时避免重复调用函数:
int* x; if ((x = foo()) || (x = bar())) { // 使用x执行操作(此时x是foo()或bar()的非空返回值) } else { // foo()和bar()均返回nullptr时执行这里 }
原理说明:
(x = foo())会先把foo()的返回值赋值给x,然后返回x本身(指针类型)。在布尔判断中,nullptr被视为false,非空指针视为true。- 因为
||是短路求值:如果foo()返回非空指针,(x = foo())为真,后面的(x = bar())会被直接跳过,完美符合你“优先用foo的返回值”的需求;如果foo()返回nullptr,才会执行x = bar(),再判断bar的返回值是否为空。 - 注意括号不能省!
=的优先级比||低,不加括号会变成x = (foo() || bar()),又回到你原来的类型转换错误。
2. C17 if初始化写法(更符合现代C风格)
如果你用的是C++17及以上版本,可以把变量声明在if语句里,让作用域更紧凑:
if (int* x = foo(); !x) { x = bar(); // foo返回空时,再尝试bar } if (x) { // 使用x执行操作 } else { // 两者均为空 }
这种写法把x的作用域限制在相关代码块内,更符合RAII原则,可读性也很好。
3. 分步赋值写法(最直观,适合新手)
如果觉得上面的写法有点“技巧性”,可以用最直白的分步逻辑,完全没有语法陷阱:
int* x = foo(); if (!x) { x = bar(); } if (x) { // 使用x执行操作 } else { // 两者均为空 }
这种写法一目了然,即使是刚接触C++的开发者也能快速理解逻辑,缺点是比前两种多了几行代码。
避坑提醒:
别用这种写法:
// 不推荐!如果foo()有副作用,会被调用两次! if (int* x = foo() ? foo() : bar()) { // ... }
这里foo()会被调用两次(一次判断,一次赋值),如果foo()包含比如修改全局变量、IO操作这类副作用,会导致逻辑错误。
内容的提问来源于stack exchange,提问作者hermit.crab
相关产品推荐
相关产品推荐

