c++ Объявление переменной внутри оператора switch

У меня есть оператор switch в моем коде C++, и я хочу объявить и использовать переменную внутри case этого оператора. Переменная будет использоваться только внутри области действия этого конкретного case.

switch(mode)
{
case abc:
    ...
    struct commonData;
    commonData = manager->getDataByIndex(this->Data.particularData);
    int someInt = 1;
    ...
    break;
case xyz:
    ...
    commonData = Manager->getDataByIndex(this->Data.particularData);
    break;
default:
    ...
    break;
}

Я попытался просто объявить, инициализировать и использовать переменную (int someInt) только внутри этого case, но это дало мне несколько ошибок компиляции... Столкнувшись с этим вопросом на SO: Почему переменные не могут быть объявлены в операторе switch?, я попытался сделать то, что предложил ответ, и добавил {} к рассматриваемому case, поэтому мой switch теперь выглядит так:

switch(mode)
{
case abc:
    {
    ...
    struct commonData;
    commonData = manager->getDataByIndex(this->Data.particularData);
    int someInt = 1;
    ...
    break;
    }
case xyz:
    ...
    commonData = manager->getDataByIndex(this->Data.particularData);
    break;
default:
    ...
    break;
}

Но теперь я получаю ошибки компиляции, которые говорят: «необъявленный идентификатор» для переменной (commonData), которая используется в случае xyz для switch.

Посмотрев на это, кажется, что эта переменная объявлена ​​внутри abc случая switch... Очевидно, что, поскольку я добавил {} к abc, пытаясь использовать его вне abc, теперь я пытаюсь использовать это выходит за рамки его объявления.

Так почему же я не могу объявить/использовать someInt так же, как commonData был объявлен/использован без необходимости {} внутри case, где он объявлен?


person Noble-Surfer    schedule 07.05.2015    source источник
comment
struct TypeNameforStruct{ // элементы структуры}; TypeNameforStruct commonData; ?   -  person 911    schedule 07.05.2015
comment
Хм? Что-то не так или неполное с кодом, который вы разместили. struct commonData объявляет не переменную, а неполный тип.   -  person Avi Berger    schedule 07.05.2015


Ответы (4)


Причина, по которой объявления некоторых переменных не разрешены в операторе switch, заключается в следующем: для потока управления на основе switch недопустимо перескакивать через инициализацию переменной.

В вашем случае я предполагаю, что тип commonData имеет тривиальную инициализацию (без конструктора и нетривиальных членов), поэтому его объявление вполне нормально, как и объявление только int someInt;. Однако int someInt = 1; не допускается, так как инициализация будет пропущена всякий раз, когда mode не является abc.

Я не совсем понимаю, что вы получите, объявив commonData только один раз, за ​​исключением того, что вы сэкономите время на наборе текста за счет сокрытия кода («откуда взялось commonData?» при чтении блока case), что никогда не бывает хорошо. торговля. Поэтому я бы просто использовал {} внутри каждого "блока" case и объявлял commonData в каждом из них, который в этом нуждается. Или объявите commonData над переключателем.

Но если вы действительно хотите, чтобы один и тот же commonData использовался всеми case и при этом был локальным для блока switch, вы можете точно настроить области действия. Что-то вроде этого:

switch(mode)
{
    SomeType commonData;
case abc:
    {
    ...
    commonData = manager->getDataByIndex(this->Data.particularData);
    int someInt = 1;
    ...
    break;
    }
case xyz:
    ...
    commonData = manager->getDataByIndex(this->Data.particularData);
    break;
default:
    ...
    break;
}

или это:

switch(mode)
{
case abc:
    SomeType commonData;
    ...
    commonData = manager->getDataByIndex(this->Data.particularData);
    {
    int someInt = 1;
    ...
    break;
    }
case xyz:
    ...
    commonData = manager->getDataByIndex(this->Data.particularData);
    break;
default:
    ...
    break;
}

Но, пожалуйста, подумай о следующем мейнтейнере и не проделывай такие трюки.


В приведенном выше ответе предполагается, что struct commonData; на самом деле является «опечаткой» в вашем коде: буквально он будет предварительно объявлять тип, а не объявлять переменную. Но это не соответствует ни использованию в остальной части вашего кода, ни тексту вашего вопроса, поэтому я позволил себе это исправить.

person Angew is no longer proud of SO    schedule 07.05.2015
comment
Спасибо за ваш ответ - действительно полезное объяснение. - person Noble-Surfer; 12.05.2015

{ .. } создает локальную область, поэтому ваше объявление переменной не будет видно в другой.

Добавьте объявление к каждому case с локальной областью действия или, если вы хотите использовать переменную вне оператора switch, объявите ее перед switch.

person Karoly Horvath    schedule 07.05.2015
comment
Ура - только что подумал об этом. Я не хочу использовать переменную вне переключателя, но кажется, что ее нужно объявить вне переключателя, чтобы ее можно было использовать только внутри одного случая. - person Noble-Surfer; 07.05.2015
comment
Это не так. Вы можете создать локальную область в коммутаторе и добавить (и использовать) переменную только в эту область. Но это не то, что вы делаете в своем примере. - person Karoly Horvath; 07.05.2015

Используйте скобки. Пример:

switch (int number) {
    case 3: { 
        int n = 5; 
        n = n*4; // random
    } break;

    case 4: {
        int a = 4;
        //  n is out of scope
    } break;
};
person Evan Carslake    schedule 07.05.2015

Порядок двоичного кода оператора switch может отличаться от исходного кода, потому что компилятор оптимизирует код в двоичное дерево поиска. Таким образом, переменные кросс-области не допускаются.

person jayatubi    schedule 07.05.2015