Для петлі всередині власних фігурних брекетів


117

Я натрапив на цей макет 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;
}

Мені було цікаво, для чого цей додатковий шар брекетів? Це з’являється кілька разів у нашій кодовій базі.


47
Вони абсолютно зайві в опублікованому вами фрагменті коду
EdChum

25
які компілятори були використані з цим кодом? Зокрема, VS 6 звик?
UKMonkey

5
@EdNorman зараз з вашою редагуванням набагато зрозуміліше. Здається, що правильна відповідь - це та, яку надає UKMonkey. За допомогою сучасного компілятора C ++ ви можете просто скинути фігурні брекети.
Jabberwocky

8
Крім того, він може бути згенерований кодом (зітхнув хтось, що тільки-но
стикається

4
Однією з можливих причин є те, якщо код колись мав (або планується мати в майбутньому) паралельні директиви OpenMP.
jamesqf

Відповіді:


286

Колись багато місяців тому VS6 існував і користувався популярністю. Однак він не відповідав ряду стандартів С ++; що було розумним на той момент, коли він був випущений напередодні (того ж року) стандарт був офіційно випущений; Наскільки я знаю, він все-таки дотримувався проекту стандарту.

Одним із стандартів, який змінився між проектом та офіційним стандартом, був термін експлуатації змінних циклу, створених у першому розділі; що призводить до неможливості компілювати наступний код

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

тому що iбув переосмислений другим для циклу.

Хоча інші компілятори також зазнали цієї помилки; Я виділяю VS6, тому що він залишався єдиною версією візуальної студії протягом декількох років після виходу стандарту, але ніколи не випускав оновлення для цього конкретного випуску; це означає, що це мало більш значний вплив.

Рішення для цього полягає в тому, щоб змусити ціле цикл у власному обсязі, як ви показали.


49
Не потрібно знаходити VS6, щоб переконатися, що @bolov, встановив "Відповідність сили в діапазоні циклу" на "Ні" у VS2015, і насолоджуйся ;-)
alain

5
@alain "варіант" Zc: forScope- "був застарілим і буде видалений у майбутньому випуску" і збирається без проблем ... Мені сумно
bolov

7
GCC до версії 2.7 також проявляв таку поведінку. Дивіться docs.freebsd.org/info/g++FAQ/g++FAQ.info.for_scope.html
Джеремі

5
@Damon це було не тоді, коли VS6 був вперше випущений; однак, коли змінилися стандарти, оновлення, яке відповідає їм, ніколи не виходило. VS6 залишався популярним протягом кількох років після зміни стандартів.
UKMonkey

7
Приписання цього гріха старого компілятора Microsoft є хибним. Така поведінка насправді була особливістю проектів стандартів C ++, і це зробили ряд компіляторів (не лише компілятори Microsoft). З пам’яті, вона була змінена в чернетці протягом приблизно 1995 року, щоб зробити змінну локальною до циклу - приблизно за три роки до ратифікації першого стандарту C ++. Тож більшість компіляторів C ++, що передбачили (близько) 1996 року, працювали саме так.
Пітер

15

{і }створить область, і якщо ви визначите деякі змінні в області, ви не можете отримати доступ до них ззовні. Але 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не буде доступний з-за меж сфери застосування.


2

У вашому конкретному прикладі немає причин для них.

Іноді ви можете створити область для змінної:

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має бути власна функція.


Гаразд, якщо ви думаєте, що це має бути у власній функції (я можу придумати багато разів, коли це додасть би лише мінімум накладних витрат, але я не збираюся туди йти) гіпотетичне питання для вас: а як бути, якщо вам потрібен конкретна локальна сфера для випадку переключення? Безумовно, буває, що додавання додаткової області (що, звичайно, функція теж) (зауважте, що для вашого прикладу я не вважаю, що окрема функція є поганою ідеєю), але це зайве, але в інших випадках це не так просто, навіть якщо є й інші способи.
Прифтан

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.