はa && b && c
言語によって定義されており、(a && b) && c
またはa && (b && c)
?
うわー、ジェリーは速かった。質問を強化するには、それは実際に重要ですか? a && b && c
またはとして解釈される間に観察可能な違いはあります(a && b) && c
かa && (b && c)
?
はa && b && c
言語によって定義されており、(a && b) && c
またはa && (b && c)
?
うわー、ジェリーは速かった。質問を強化するには、それは実際に重要ですか? a && b && c
またはとして解釈される間に観察可能な違いはあります(a && b) && c
かa && (b && c)
?
§5.14/1: 「&& 演算子は左から右にグループ化されます。[...] & とは異なり、&& は左から右への評価を保証します。最初のオペランドが false の場合、2 番目のオペランドは評価されません。」
いつ、またはどのように重要かについて: 組み込み型の場合に本当にそうであるかどうかはわかりません。ただし、問題になるような方法でオーバーロードすることは可能です。例えば:
#include <iostream>
class A;
class M {
int x;
public:
M(int x) : x(x) {}
M &operator&&(M const &r);
M &operator&&(A const &r);
friend class A;
};
class A {
int x;
public:
A(int x) : x(x) {}
A &operator&&(M const &r);
A &operator&&(A const &r);
operator int() { return x;}
friend class M;
};
M & M::operator&&(M const &r) {
x *= r.x;
return *this;
}
M & M::operator&&(A const &r) {
x *= r.x;
return *this;
}
A &A::operator&&(M const &r) {
x += r.x;
return *this;
}
A &A::operator&&(A const &r) {
x += r.x;
return *this;
}
int main() {
A a(2), b(3);
M c(4);
std::cout << ((a && b) && c) << "\n";
std::cout << (a && (b && c)) << "\n";
}
結果:
9
16
警告: これは、問題にする方法を示しているだけです。誰にでもそうするように特に勧めているわけではありませんが、どうしてもそうしたいのであれば、違いを生む状況を作り出すことができるということを示しているだけです。
a && b
が false の場合、その&& c
部分はテストされません。そうです、それは重要です (少なくとも、操作を左から右に順序付ける必要があるという点で)。 &&
は本質的に連想操作です。
関連プロパティ
同じ結合演算子が 1 行に 2 回以上出現する式内では、オペランドの順序が変更されない限り、演算が実行される順序は重要ではありません。つまり、そのような式で括弧を並べ替えても、その値は変わりません。
a && (b && c)
したがって、またはとして記述しても(論理的に)問題ありません(a && b) && c
。どちらも同等です。ただし、操作の順序を変更することはできません (たとえば、a && c && b
は と同等ではありませんa && b && c
)。