commutateur "transfert de contrôle contourne l'initialisation de:" lors de l'appel d'une fonction

j'obtiens un "transfert de contrôle contourne l'initialisation de l':" erreur quand j'essaie de compiler le commutateur suivant:

switch (retrycancel)
{
    case 4:    //The user pressed RETRY
        //Enumerate all visible windows and store handle and caption in "windows"
        std::vector<MainHandles::window_data> windows = MainHandles().enum_windows().get_results(); 
        break;

    case 2: 
        //code
}

Il a quelque chose à voir avec mon appel mon énumérer fonction. Si il n'est pas permis d'appeler une fonction dans un switch, est-il une solution pour ce genre de problème?

44
demandé sur user0118999881999119725 3 2011-02-28 00:59:36

2 réponses

section 6.6.4 de la norme C++:

la déclaration Goto inconditionnellement transfère le contrôle à l'instruction marqué par l'identificateur. Le identifiant doit être une étiquette (6.1) situé dans la fonction courante.

l'article 6.7 de la norme C++:

Il est possible de transférer dans un bloc, mais pas d'une manière qui contourne déclarations avec initialisation. Un programme qui saute à partir d'un point lorsqu'une variable locale avec automatique durée de stockage n'est pas dans le champ d'application à un point où il est dans la portée est ill-formé à moins que la variable a POD type (3.9) et déclaré sans initialiseur

Italiques ajout par moi. Depuis switch vraiment goto dans le déguisement, vous êtes à la rencontre de ce comportement. Pour résoudre cela, ajoutez des accolades si vous devez utiliser un switch

switch (retrycancel)
    {
    case 4:
    {
        const std::vector<MainHandles::window_data> windows(
            MainHandles().enum_windows().get_results()
        );
        break;
    }
    case 2: 
        //code
    }

ou se refacter en if/else

if (retrycancel == 4) {
    const std::vector<MainHandles::window_data> windows(
        MainHandles().enum_windows().get_results()
    );
} else if (retrycancel == 2)
    // code
} else {
    ...
}

bien qu'il ne soit pas évident pour moi ce que vous espérez accomplir en créant le windowsvector dans un switch, de sorte que vous voudrez peut-être repenser votre conception. Remarque: j'ai ajouté un const qualificatif de windows puisqu'il n'est pas modifié dans votre exemple.

63
répondu Sam Miller 2011-02-27 22:19:38

un interrupteur est essentiellement un goto, qui est, il est un goto pour l'étiquette appropriée. Le standard C++ interdit à un goto de contourner une initialisation d'un objet non-POD. Prenez la déclaration vectorielle dans des bracelets et cela résoudra le problème

switch (retrycancel)
    {
     case 4:                //The user pressed RETRY
     {
        std::vector<MainHandles::window_data> windows = MainHandles().enum_windows().get_results(); //Enumerate all visible windows and store handle and caption in "windows"
        break;
     }
    case 2: 
        //code
    }
11
répondu Armen Tsirunyan 2011-02-27 22:06:15