是否保证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++ 中:

[intro.execution]

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

[expr.log.and]

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].

中有类似的注释