Re: [问题] if(X||Y)以及if(a()||b())的差异

楼主: poyenc (发箍)   2020-12-16 00:01:35
※ 引述《ironstark (Stark)》之铭言:
: 不好意思想请问一下各位大大
: 两个function,a(),b(),回传bool
: X=a(),Y=b()
: 这样 if(X||Y)以及if(a()||b())两种写法在执行上会有什么差异呢?
: 这部分用到的观念是什么或是该搜寻什么关键字
: 小弟新手入门对一些细节不太熟悉,还请各位帮忙解惑,谢谢大家!
你可以尝试作实验画个真值表 (truth table) 来观察行为, 不过这代表我们
需要有办法决定 a()/b() 的回传值. 除了直接修改函式实作, 最快的方式就
是透过函式模板来作客制化:
template <bool B>
bool a() { std::cout << "a() "; return B; }
a<true>(); // print "a()", return true
a<false>(); // also print "a()", return false
a()/b() 都作一个模板我们就可以填完真值表内容:
┌──┬──┬────┐
│a() │b() │ output │
├──┼──┼────┤
│ F │ F │a() b() │
├──┼──┼────┤
│ F │ T │a() b() │
├──┼──┼────┤
│ T │ F │a() │
├──┼──┼────┤
│ T │ T │a() │
└──┴──┴────┘
范例: https://godbolt.org/z/TojhP5
从上表可以看到当 a() 回传值为 true 的时候, b() 就不会被呼叫. 一般人
可能会用short-circuit evaluation 来称呼它, 甚至撰写程式码的时候会依
赖这个行为 (为了写出主观简洁的程式码).
但小弟要在这里说: 这是不好的观念. 因为 C++ 允许使用者对运算子作重载
(overloading), 所有的重载版本 operator||() 以及 operator&&() 都没有
上面提到的short-circuit 行为. 我们可以将函式 a()/b() 改成回传列举型
别 Bool 来实验看看:
范例: https://godbolt.org/z/K1hGGf
因为 short-circuit 只作用在俗称内建型别 (primitive type) 算子上,
为了避免混淆, 有两派人马分别采取不同策略来避免预期以外的行为发生:
1. 一律不重载 operator&&() 及 operator||()
e.g. 《More Effective C++》Item #7
《C++FAQ》What are some guidelines / "rules of thumb"
for overloading operators?
2. 重载 operator&&() 及 operator||(), 但不对求值顺序/与否作假设
无论如何, 知道这些考量有助于写出更安全的程式. :)
作者: Lipraxde (Lipraxde)   2020-12-16 00:37:00
对耶,还有重载这件事!
作者: Schottky (顺风相送)   2020-12-16 01:22:00
推,忘了还有 overloading
作者: jack82822005 (小郭郭)   2020-12-16 07:38:00
重载的时候可以定义成有短路功能的版本吗?
作者: uranusjr (←這人是超級笨蛋)   2020-12-16 10:53:00
这也是很多语言是不允许重载 logical operators 的理由
作者: F04E (Fujitsu)   2020-12-16 11:50:00
作者: Schottky (顺风相送)   2020-12-16 16:07:00
都已经重载了compiler哪知道你的重载里面是怎么处理那要呼叫重载函式就得把两个参数都准备好给你也不可能先给一个,叫函式先用用看,需要另一个再跟我讲
作者: VictorTom (鬼翼&娃娃鱼)   2020-12-21 14:03:00
推:)
作者: KevinR (Kevin)   2020-12-23 18:42:00
这篇怎么没m
作者: longlongint (华哥尔)   2020-12-26 18:27:00
我也觉得short cut 尽量少用但是公司code review 完就被改成 short cut 嘻嘻
作者: KevinR (Kevin)   2020-12-26 19:18:00
C++17 导入的if constexpr也不能用short-circuit
作者: LPH66 (-6.2598534e+18f)   2020-12-27 04:22:00
if constexpr 的语意上本来就没有执行期判断要说这没有短路有点微妙, 毕竟求值不是你的程式在求
作者: F04E (Fujitsu)   2020-12-27 09:53:00
啊就执行期if跟编译期if的不同点, 反正也编不过.

Links booklink

Contact Us: admin [ a t ] ucptt.com