http://en.cppreference.com/w/cpp/language/operator_precedenceの C++ 演算子の優先順位テーブル(規範的ではないことはわかっていますが、標準では優先順位や結合性については言及されていません) は、単項演算子を右/左結合としてマークします。 .
別の質問に関する議論から、私には疑問が残ります。単項演算子が結合的であることは理にかなっていますか?
http://en.cppreference.com/w/cpp/language/operator_precedenceの C++ 演算子の優先順位テーブル(規範的ではないことはわかっていますが、標準では優先順位や結合性については言及されていません) は、単項演算子を右/左結合としてマークします。 .
別の質問に関する議論から、私には疑問が残ります。単項演算子が結合的であることは理にかなっていますか?
これは、結合性が文法から派生する方法の人工物にすぎません。
足し算が左結合である理由は、additive-expression の生成の 1 つが、additive - expression + multiplicative - expressionであり、additive-expression が左側にあるためです。だからあなたが見るとき:
a + b + c
(a + b) + c
生成を一致させる唯一の方法はa + b
、加算式および乗算c
式として使用することであるため、これは と同等でなければなりません。それ自体は加法式ですが、乗法式ではないため、加法式として取得しようとすると、生成物と一致しません。a
b + c
a + b + c
a
まだ読んでいない場合は、セマンティクスを無視して「式」の章を一通り読むことをお勧めします。文法生成だけを見てください。そうすれば、優先順位と結合性が文法によってどのように定義されるかがわかります。大きなトリックは、すべての「優先順位の高い」タイプの式は「優先順位の低い」タイプの式であるということです。したがって、すべての乗算式は加算式ですが、その逆ではありません。これにより、乗算は加算よりも「より緊密にバインド」されます。
前置単項演算子は文法で次のように定義されます: unary-expression : ++ cast-expressionなどで、演算子は左側が接頭辞、右側が接尾辞です。つまり、接尾辞の場合は左側に、接頭辞の場合は右側に「括弧を挿入」します。つまり、グループ化は後置演算子では左から右、前置演算子では右から左であると言えます。実際、C++ 標準はまさにそれを示しています (C++03 では 5.2/1 および 5.3/1)。この単項グループ化を「結合性」と呼ぶのは、用語の乱用または少なくとも新しい造語である可能性があります。しかし、何を意味しなければならないかは明らかなので、それは主要なものではありません。
ここでの二項演算子と単項演算子の唯一の違いは、二項演算子が反対方向にグループ化されている場合でも構文が意味をなすことa - b - c
ですa - (b - c)
。驚くべきことですが、それ以外の場合は言語に影響しません。!!a
単項演算子では、 as としてグループ化することは驚くべきことではありません。(!!)a
言語は、サブ式の意味!!
も提供する必要がありますが、現在はありません。関数型言語はそれに意味を与えることができます:と!!
から構成される関数、つまり と同じ操作を意味するかもしれませんが、C++ には関数や演算子を構成する概念がありません。C++ がその意味を提供する必要がない理由は、!
!
static_cast<bool>()
!
「グループは右から左へ」。これは (文法の大きなトリックのため)!!
構文的に正しい表現ではないことを示す別の方法であり、決して何かの部分表現ではありません。
そうです、前置演算子は右から左にグループ化し、後置演算子は左から右にグループ化すると言うのは理にかなっています。しかし、C++ 言語について私たちが知っている他のことから、このようにしなければならないことも「明らか」です。
ところで、少なくとも C++ で技術的に言えば、postfix++
は単項演算子ではないと思います。後置演算子です。しかし、それは標準の用語であることを除いて、実際には問題ではありません。明らかに演算子であり、オペランドが 1 つあるため、英語の「単項」もそうです。
次のコードを検討してください
int *p;
*p++;
式は、 (p が指すオブジェクトをインクリメントする) または(p が指す次のオブジェクトを指す)*p++
として評価できます。(*p)++
*(p++)
単項演算子は右結合であるため、式*p++
は として評価され*(p++)
ます。(カーニハンとリッチーを読んでいるときにこれを思いつきました。)
優先順位と結合性が変更され、後置演算子が逆参照演算子++
よりも優先されているようです。*
C11 によると、上記の式は として評価され*(p++)
ます。
これにより、単項演算子に結合性がある理由がより明確になることを願っています。
これを指摘してくれたルシアン・グリゴレに感謝します。
単項演算子の場合の演算子の結合性は、演算子がオペランドのどちら側に現れるかを決定するだけです。
確かではありませんが、以下が有効であれば、はい。
++i--
しかし、そうではなく、エラーをスローします
lvalue required as increment operand
単項演算子のすべての動作は、優先順位のみで説明できます。