2011-02-27 11 views
40

consigo una "transferencia de control anula la inicialización de:" error cuando intento para construir el siguiente modificador:interruptor de "transferencia de control no pasa por la inicialización de:" cuando se llama a una función

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 
} 

Tiene algo que hacer con mi llamar a mi función de enumerar. Si no se permite llamar a una función desde un interruptor, ¿hay alguna solución para este tipo de problema?

Respuesta

55

sección 6.6.4 de la norma C++:

La instrucción goto incondicionalmente transfiere el control a la declaración etiquetado por el identificador. El identificador debe ser una etiqueta (6.1) ubicada en la función actual.

sección 6.7 de la norma C++:

Es posible transferir en un bloque , pero no de una manera que no pasa por declaraciones con inicialización. Un programa que salta desde un punto donde una variable local con una duración automática de almacenamiento no está en el ámbito de un punto donde está en su alcance es mal formada a menos que la variable tiene POD tipo (3.9) y se declara sin un inicializador

énfasis añadido por mí. Como switch es realmente goto disfrazado, te encuentras con este comportamiento. Para solucionar esto, agregar las llaves si debe utilizar un switch

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

o refactorizar en if/else

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

Aunque no es obvio para mí lo que esperas lograr con la creación de la windowsvector dentro de un switch, por lo que es posible que desee reconsiderar su diseño. Nota Agregué un calificador const a windows ya que no está modificado en su ejemplo.

+0

Gracias a su respuesta, fue una tarde ayer poco, así que copié la llamada de función incorrecta en el interruptor, el "real" tiene más sentido ;-). Sin embargo, iré con el loop else sugerido. ¿Cuál es la fuente oficial del estándar de C++ que citó? – Lumpi

+0

@Lumpi el estándar ISO C++, compré una copia hace algún tiempo. –

+1

@SamMiller: ¿Puede explicar en términos más simples por qué se requieren llaves en ciertos casos de interruptores? Estaba creando un nuevo objeto en una de las cajas del conmutador y obtuve un error de compilación, pero si declaro o inicializo una variable normal, digo int. No obtengo ningún error – tanz

11

un interruptor es esencialmente un goto, es decir, es un goto a la etiqueta correspondiente. El estándar de C++ prohíbe a un goto eludir una inicialización de un objeto que no sea POD. Tome la declaración vector en los frenos y se va a resolver el problema

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 
    } 
+0

¡Gracias! Como mencionaste, es un goto y como estoy tratando de aprender una programación adecuada, creo que iré con el if if si el bloque es sugerido por Sam Miller. – Lumpi

Cuestiones relacionadas