web-dev-qa-db-ja.com

独自の中括弧内のforループ

私はこのfor-loopレイアウトに出くわしました:

#include <iostream>
int main()
{
    {
        for (int i = 0; i != 10; ++i)
        {
            std::cout << "delete i->second;" << std::endl;
        }
    }

    {
        for (size_t i = 0; i < 20; ++i)
        {
            std::cout << "delete m_indices[i];" << std::endl;
        }
    }
    return 0;
}

私はこの追加のブレース層が何のためにあるのか疑問に思いましたか?これは私たちのコードベースに数回現れます。

116
Ed Norman

むかしむかし、何月も前、 VS6 が存在し、流行していました。しかしながら、多くのC++標準には準拠していません。これは、規格が正式にリリースされる直前(同年)にリリースされた時点では妥当でした。しかし私の知る限りでは規格のドラフトに準拠していました。

ドラフトと公式の標準との間で変更された標準の1つは、最初のセクションで作成されたforループ変数の寿命です。次のコードのコンパイルに失敗する

{
    for (int i=0; i<1; ++i){}
    for (int i=0; i<2; ++i){}
}

なぜならiは2番目のforループによって再定義されたからです。

他のコンパイラもこのバグを抱えていましたが。私はVS6を強調しています。なぜならそれは規格のリリース後何年もの間ビジュアルスタジオの唯一のバージョンであり続けたが、この特定の問題のためのアップデートを決してリリースしなかったからです。それがより重大な影響を与えたことを意味します。

これに対する解決策は、あなたが示したようにforループ全体をそれ自身の範囲に強制することです。

287
UKMonkey

{}はスコープを作成します。スコープ内でいくつかの変数を定義した場合、外部からそれらにアクセスすることはできません。しかしforはすでにそのスコープを作成しています。そう

{for(int i = 0; i < count; ++i){}} 

と同じです

for(int i = 0; i < count; ++i){}

しかし、あなたがそれらの間に何かを定義するならば、違いがあります

{int a = 0; for(int i = 0; i < count; ++i){}}

この例では、aは外部スコープからアクセスできません。

15
cokceken

{}中括弧で囲まれた ブロックスコープ です。通常、 自動ストレージ の領域をマークするために使用されます。あなたの場合、 forループ は標準C++では独自のスコープを持っているので何もしないようです。

2
Ron

あなたの特定の例ではそれらの理由はありません。

時々、変数のスコープを作成したくなるでしょう。

float average;
// ...

{
int sum = 0;
for (int i = 0; i < count; ++i)
{
   sum += v[i];
}
average = (float)sum / count;
}

// use average
// sum not in scope here

しかし私はこれをアンチパターンと見ています。通常、これを実行する必要があると思った場合は、ほとんどの場合、forは独自の関数になります。

2
bolov