17

おそらく私は錆びてきています(最近Pythonで書いています)。

なぜこれがコンパイルされないのですか?

if ( (int i=f()) == 0)

()周りがなければ、int i=f()私は別の、はるかに合理的なエラーiがブール値ではないことを取得します。でも、そもそもかっこが欲しかったのです!

私の推測では、括弧を使用すると式になり、式で宣言ステートメントを使用することはできません。そうですか?もしそうなら、それはC ++の構文の癖の1つですか?

ところで、私は実際にこれをやろうとしていました:

if ( (Mymap::iterator it = m.find(name)) != m.end())
    return it->second;
4

4 に答える 4

38

C ++のステートメントで変数を宣言できますがif、直接初期化での使用に制限されており、ブール値に変換する必要があります。

if (int i = f()) { ... }

C ++には、「宣言式」、つまり変数を宣言する[sub-]式として記述できるものはありません。

実際、私は標準で句を調べたところ、6.4 [stmt.select]段落1に従って、両方の形式の初期化がサポートされています。

...
condition:
   expression
   attribute-specifier-seqopt decl-specifier-seq declarator = initializer-clause
   attribute-specifier-seqopt decl-specifier-seq declarator braced-init-list
...

つまり、次のように書くこともできます。

if (int i{f()}) { ... }

明らかに、C ++ 2003には中括弧の初期化がないため、これはC++2011でのみ機能します。

于 2012-01-22T13:46:42.497 に答える
20

スコープに問題があります。

次のコードを検討してください。

if ((int a = foo1()) || (int b = foo2()))
{
    bar(b);
}

bはブロック内で宣言されていますか?foo1()trueを返す場合はどうなりますか?

于 2012-01-22T13:45:16.953 に答える
5

変数はifステートメント(またはforまたはwhile)で宣言できますが、外側の括弧ブロックでのみ宣言でき、boolに変換できる必要があります。

あなたの推測は基本的に正しいです、それは許されていません

(int i = 42;)

初期化を伴う有効な宣言ではありません。

追加の行が1つ必要です。

Mymap::iterator it;
if ( (it = m.find(name)) != m.end())
    return it->second;

でもそれなら書くほうがいい

Mymap::iterator it = m.find(name);
if ( it != m.end() ) 
    return it->second;

returnこの行を本当に戻したい場合は、の後に行を置くことができifます。少なくとも私にとっては、これは読みやすさを損なうことはありませんが、他の人はそれが違うと思うかもしれません。

本当に、本当にイテレータを宣言し、それをif条件でブール値として使用したい場合は、次のことができます。

if ( struct { int it; operator bool() { return it != m.end; } } s = { m.find(name) } )
    return s.it->second;

しかし、私はこれを有害だと思います;-)

于 2012-01-22T14:04:06.013 に答える
0

書けないのは本当です

if ( (int i=f()) == 0)

しかし、あなたは完全に書くことができます

if ( int i=f())

したがって、演算子を使用して、次の&&ような1つのステートメントで両方の操作を実行できます。

if ( int i=1 && (i=f()) == 0)

i0以外の値で初期化する必要があり、コンパイラが左から右への評価を適用する場合は、これが最初の条件である必要があります。

ただし、残念ながら、2番目の例で示されているように、イテレータの場合は適用されません。

于 2015-01-09T19:28:00.120 に答える