106

今日、いくつかの Visual C++ コードを書いているときに、私を驚かせたものに出くわしました。C++ は bool の ++ (インクリメント) をサポートしているようですが、 -- (デクリメント) はサポートしていないようです。これは単なるランダムな決定ですか、それともこれには何らかの理由がありますか?

これはコンパイルされます:

static HMODULE hMod = NULL;
static bool once = false;
if (!once++)
    hMod = LoadLibrary("xxx");

これはしません:

static HMODULE hMod = NULL;
static bool once = true;
if (once--)
    hMod = LoadLibrary("xxx");
4

4 に答える 4

94

これは、ブール値として整数値を使用してきた歴史に由来しています。

xであるintが、私はそれをブール値として使用しているので、if(x)...インクリメントすると、操作前の真理値が何であれ、それtrue以降の真理値が得られます(オーバーフローを除く)。

ただし、 (積分値が1の場合)または(積分値がそれ以外の場合-特にこれには0 [ ]と2が含まれる)または(積分値が1の場合)になる可能性があるため、--の真理値のみの知識の結果を予測することは不可能です。もっと[ ])。xfalsetruefalsetrue

速記としては機能しました++が、機能--しませんでした。

++これとの互換性のためにboolsで許可されていますが、その使用は標準では非推奨であり、C++17で削除されました。


これは、私がブール値としてのみ使用することを前提としています。つまり、それ自体でオーバーフローを引き起こすのに十分な頻度でx実行するまで、オーバーフローは発生しません。++使用するタイプがcharで、CHAR_BITS5のような低いものでも、これが機能しなくなるまでの32倍です(これは悪い習慣であるために十分な議論ですが、私はその習慣を擁護していません。なぜそれが機能するのかを説明するだけです)intもちろん、32ビットの場合++、これが問題になる前に2^32回使用する必要があります。ただし、の値を1から始めた場合、または0から始めて、前に1回だけ使用した場合に--のみ結果が得られます。falsetrue++

これは、0より少し小さい値で開始する場合は異なります。実際、そのような場合、最終的に次のような値になりたい場合が++あります。false

int x = -5;
while(++x)
  doSomething(x);

ただし、この例では、条件付きを除くすべての場所として扱わxれるため、次のようになります。int

int x = -5;
while(++x != 0)
  doSomething(x);

xこれは、ブール値としてのみ使用するのとは異なります。

于 2010-08-10T15:26:20.943 に答える
29

ANSI ISO IEC 14882 2003 (c++03):

5.2.6-2

後置 -- のオペランドは、オペランドが bool 型であってはならないことを除いて、後置 ++ 演算子と同様にデクリメントされます。[注: プレフィックスの増分と減分については、5.3.2 を参照してください。]

そして当然のことながら...

5.3.2-2

プレフィックス -- のオペランドは、1 を減算することによって変更されます。オペランドは bool 型であってはなりません。prefix -- のオペランドの要件とその結果のプロパティは、その他の点では prefix ++ の要件と同じです。[注: 接尾辞のインクリメントとデクリメントについては、5.2.6 を参照してください。]

また、5.6.2-1 および 5.3.2-1 では、bool の ++ は true であると述べられており、Annex D-1 では、bool の ++ は非推奨であると述べられています。

于 2010-08-10T15:22:26.143 に答える
9

歴史的な理由により、これはサポートされていました。ただし、注意してください... ++演算子でbool型のオペランドを使用することは非推奨です。C++標準(n3092)のセクション5.3.2を参照してください。

5.3.2インクリメントとデクリメント[expr.pre.incr]

  • プレフィックス++のオペランドは、1を追加することによって変更されるか、boolの場合はtrueに設定されます(この使用は非推奨です)。オペランドは変更可能な左辺値でなければなりません。オペランドの型は、算術型または完全に定義されたオブジェクト型へのポインタでなければなりません。結果は更新されたオペランドです。これは左辺値であり、オペランドがビットフィールドの場合はビットフィールドです。xがbool型でない場合、式++xはx+ = 1と同等です[注:変換の詳細については、加算(5.7)および代入演算子(5.17)の説明を参照してください。—エンドノート]
  • 接頭辞--のオペランドは、1を引くことによって変更されます。オペランドはbool型であってはなりません。プレフィックス-のオペランドの要件とその結果のプロパティは、それ以外はプレフィックス++の要件と同じです。
于 2010-08-10T15:28:33.093 に答える
3
  • 古い標準 (C++98) ではエラーにはなりません。
  • 新しい標準が増加すると、ブール値は非推奨になります。(C++11)
  • C++17 まではブール値でインクリメントを使用できます。
于 2016-03-23T06:18:38.063 に答える