Kendi kaşlı ayraçları içindeki döngü için


117

Bu for-loop düzenine rastladım:

#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;
}

Merak ediyordum da bu fazladan diş teli tabakası ne işe yarıyor? Bu, kod tabanımızda birkaç kez görünür.



25
bu kodla hangi derleyiciler kullanıldı? Özellikle VS 6 kullanıldı mı?
UKMonkey

5
@EdNorman şimdi yaptığınız düzenlemeyle çok daha net. Görünüşe göre doğru cevap UKMonkey tarafından verilen cevaptır. Modern C ++ derleyicisiyle küme parantezlerini basitçe kaldırabilirsiniz.
Jabberwocky

8
Alternatif olarak, kod üretilebilir (Rhapsody ile yeni
tanışmaya

4
Olası bir neden, kodun bir zamanlar OpenMP paralel yönergelerine sahip olması (veya gelecekte olması amaçlanması) olabilir.
jamesqf

Yanıtlar:


286

Bir zamanlar, birçok ay önce VS6 vardı ve popülerdi. Ancak bir dizi C ++ standardına uymakta başarısız oldu; Standart resmi olarak serbest bırakılmadan hemen önce (aynı yıl) piyasaya sürüldüğü sırada makul olan; ancak benim bildiğim kadarıyla standardın taslağına bağlı kaldı.

Taslak ile resmi standart arasında değişen standartlardan biri, ilk bölümde oluşturulan döngü değişkenlerinin yaşam süresiydi; aşağıdaki kodun derlenememesine yol açar

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

çünkü iikinci for döngüsü tarafından yeniden tanımlandı.

Diğer derleyiciler de bu sorunu yaşarken; VS6'yı vurguluyorum çünkü standardın yayınlanmasından sonra birkaç yıl boyunca görsel stüdyonun tek sürümü olarak kaldı, ancak bu özel sayı için hiçbir zaman bir güncelleme yayınlamadı; daha önemli bir etkisi olduğu anlamına geliyor.

Bunun bir çözümü, tüm for döngüsünü sizin de gösterdiğiniz gibi kendi kapsamına zorlamaktır.


49
@Bolov'u görmek için VS6'yı bulmaya gerek yok, VS2015'te "Döngü Kapsamında Güç Uyumluluğu" seçeneğini "Hayır" olarak ayarlayın ve keyfini çıkarın ;-)
alain

5
@alain "seçeneği 'Zc: forScope-' kullanımdan kaldırıldı ve gelecekteki bir sürümde kaldırılacak" ve sorunsuz bir şekilde
derleniyor

7
2.7 sürümünden önceki GCC de bu davranışı sergiliyordu. Bkz docs.freebsd.org/info/g++FAQ/g++FAQ.info.for_scope.html
Jeremy

5
@Damon VS6 ilk piyasaya çıktığında değildi; ancak standartlar değiştiğinde bunlara uyan bir güncelleme asla yayınlanmadı. VS6, standartların değiştirilmesinden sonra birkaç yıl boyunca popülerliğini korudu.
UKMonkey

7
Bunu eski bir Microsoft derleyicisinin günahına atfetmek sahtedir. Bu davranış aslında taslak C ++ standartlarının bir özelliğiydi ve birkaç derleyici bunu yaptı (yalnızca Microsoft derleyicileri değil). Bellekten, değişkeni döngüye yerel hale getirmek için yaklaşık 1995 yılında bir taslakta değiştirildi - ilk C ++ standardı onaylanmadan yaklaşık üç yıl önce. Yani (yaklaşık) 1996'dan önce çalışan çoğu C ++ derleyicisi bu şekilde çalıştı.
Peter

15

{ve }bir kapsam oluşturur ve kapsamda bazı değişkenler tanımlarsanız bunlara dışarıdan erişemezsiniz. Ama forzaten bu kapsamı yaratın. Yani

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

aynıdır

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

ancak aralarında bir şey tanımlarsanız,

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

Bu örnekte, akapsam dışından erişilemez.


2

Sizin özel örneğinizde onlar için hiçbir sebep yok.

Bazen bir değişken için bir kapsam oluşturmak isteyebilirsiniz:

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

Ancak bunu bir anti-model olarak görüyorum. Genellikle, bunu yapmaya ihtiyaç duyarsanız, büyük olasılıkla forkendi işlevi olmalıdır.


Tamam, eğer kendi işlevinde olması gerektiğini düşünüyorsanız (bunun en azından genel gider ekleyeceği birçok kez düşünebilirim ama oraya gitmeyeceğim) sizin için varsayımsal bir soru: peki ya bir bir anahtar durumu için belirli yerel kapsam? Kesinlikle ek bir kapsam eklemenin (ki elbette bir işlev de yapar) (örneğin, sizin örneğiniz için ayrı bir işlevin kötü bir fikir olduğunu düşünmüyorum) gereksizdir, ancak diğer zamanlarda bile o kadar basit değildir. başka yollar da var.
Pryftan

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.