是否保证bitwise "and" for bool不短路?
Is it guaranteed that bitwise "and" for bool does not short circuit?
我最近发现了一个看起来像这样的代码片段:
bool MyClass::do_work()
{
bool success = true;
for (auto const& worker : m_workers)
{
success &= worker.do_work(); // worker.do_work() returns a bool
}
return success;
}
如果我理解正确的话,函数returns true
if all workers return true
and it returns false
如果任何工人 return 为假。但是,它总是评估所有工人(这是需要的)。不涉及短路评估,因为使用了按位运算符 &=
而不是逻辑运算符 &&
.
这种行为有保障吗?确切地说,是否保证按位 &
总是计算两个操作数,即使它们是 bool
类型?我遇到了许多关于 &&
的保证短路评估的 SO 答案,但其中 none 声明 &
.
有保证的非短路评估
如果保证了这种行为,这是一种好的编程风格吗?看了一下就明白了这个函数,因为我以前没有见过这种风格,一开始我很困惑是否涉及短路评估。
是否有比以下更好的选择?
bool MyClass::do_work()
{
bool success = true;
for (auto const& worker : m_workers)
{
if (!worker.do_work())
{
success = false;
}
}
return success;
}
除非标准明确指定,否则运算符的所有操作数都将被计算且未排序1 在 C++ 中:
Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced.
[...]
The value computations of the operands of an operator are sequenced before the value computation of the result of the operator. [...]
我想到的唯一三个例外是 &&
、||
和 ?:
运算符2.
标准甚至提到 &&
3:
Unlike &
, &&
guarantees left-to-right evaluation: the second operand is not evaluated if the first operand is false
.
至于这是否是好的编程风格,这是基于意见的。
1 Unsequenced 基本上意味着如果你有 A @ B
(其中 @
是一个运算符),B
(及其副作用)可以在 A
之前进行评估,这就是为什么构造 i++ + ++i
are undefined behavior.
2 请注意,对于重载的 &&
和 ||
运算符,这不再正确,因为两个操作数都被评估了。 ?:
不能重载。
3 |
在 [expr.log.or].
中有类似的注释
我最近发现了一个看起来像这样的代码片段:
bool MyClass::do_work()
{
bool success = true;
for (auto const& worker : m_workers)
{
success &= worker.do_work(); // worker.do_work() returns a bool
}
return success;
}
如果我理解正确的话,函数returns true
if all workers return true
and it returns false
如果任何工人 return 为假。但是,它总是评估所有工人(这是需要的)。不涉及短路评估,因为使用了按位运算符 &=
而不是逻辑运算符 &&
.
这种行为有保障吗?确切地说,是否保证按位 &
总是计算两个操作数,即使它们是 bool
类型?我遇到了许多关于 &&
的保证短路评估的 SO 答案,但其中 none 声明 &
.
如果保证了这种行为,这是一种好的编程风格吗?看了一下就明白了这个函数,因为我以前没有见过这种风格,一开始我很困惑是否涉及短路评估。
是否有比以下更好的选择?
bool MyClass::do_work()
{
bool success = true;
for (auto const& worker : m_workers)
{
if (!worker.do_work())
{
success = false;
}
}
return success;
}
除非标准明确指定,否则运算符的所有操作数都将被计算且未排序1 在 C++ 中:
Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced. [...] The value computations of the operands of an operator are sequenced before the value computation of the result of the operator. [...]
我想到的唯一三个例外是 &&
、||
和 ?:
运算符2.
标准甚至提到 &&
3:
Unlike
&
,&&
guarantees left-to-right evaluation: the second operand is not evaluated if the first operand isfalse
.
至于这是否是好的编程风格,这是基于意见的。
1 Unsequenced 基本上意味着如果你有 A @ B
(其中 @
是一个运算符),B
(及其副作用)可以在 A
之前进行评估,这就是为什么构造 i++ + ++i
are undefined behavior.
2 请注意,对于重载的 &&
和 ||
运算符,这不再正确,因为两个操作数都被评估了。 ?:
不能重载。
3 |
在 [expr.log.or].