¿Por qué no se puede aplicar la declaración de cambio a las cadenas?

Resuelto yesraaj asked hace 15 años • 23 respuestas

Al compilar el siguiente código aparece el mensaje de error: type illegal.

int main()
{
    // Compilation error - switch expression of type illegal
    switch(std::string("raj"))
    {
    case"sda":
    }
}

No puedes usar cadenas ni en switchni en case. ¿Por qué? ¿Existe alguna solución que funcione bien para admitir una lógica similar a la de encender cadenas?

yesraaj avatar Mar 16 '09 19:03 yesraaj
Aceptado

La razón tiene que ver con el sistema de tipos. C/C++ realmente no admite cadenas como tipo. Apoya la idea de una matriz de caracteres constante, pero en realidad no comprende completamente la noción de cadena.

Para generar el código para una declaración de cambio, el compilador debe comprender lo que significa que dos valores sean iguales. Para elementos como ints y enumeraciones, esta es una comparación de bits trivial. Pero, ¿cómo debería el compilador comparar 2 valores de cadena? Distingue entre mayúsculas y minúsculas, no distingue entre mayúsculas y minúsculas, tiene en cuenta la cultura, etc. Sin un conocimiento total de una cadena, esto no se puede responder con precisión.

Además, las declaraciones de cambio de C/C++ normalmente se generan como tablas de rama . No es tan fácil generar una tabla de ramas para un cambio de estilo de cadena.

JaredPar avatar Mar 16 '2009 12:03 JaredPar

Como se mencionó anteriormente, a los compiladores les gusta crear tablas de búsqueda que optimicen switchlas declaraciones a una sincronización cercana a O(1) siempre que sea posible. Combine esto con el hecho de que el lenguaje C++ no tiene un tipo de cadena: std::stringes parte de la biblioteca estándar, que no es parte del lenguaje per se.

Le ofreceré una alternativa que quizás desee considerar; la he usado en el pasado con buenos resultados. En lugar de cambiar la cadena en sí, cambie el resultado de una función hash que utiliza la cadena como entrada. Su código será casi tan claro como cambiar la cadena si está utilizando un conjunto predeterminado de cadenas:

enum string_code {
    eFred,
    eBarney,
    eWilma,
    eBetty,
    ...
};

string_code hashit (std::string const& inString) {
    if (inString == "Fred") return eFred;
    if (inString == "Barney") return eBarney;
    ...
}

void foo() {
    switch (hashit(stringValue)) {
    case eFred:
        ...
    case eBarney:
        ...
    }
}

Hay un montón de optimizaciones obvias que prácticamente siguen lo que haría el compilador de C con una declaración de cambio... es curioso cómo sucede eso.

D.Shawley avatar Mar 16 '2009 12:03 D.Shawley