2011-11-08 13 views
14

Recibo un error de "expresión de caso no constante" en una instrucción de cambio. Sin embargo, el encabezado proporciona una definición para las constantes utilizadas, y el constructor proporciona la inicialización para ellas en su lista de inicialización.Expresión de caso no constante

Además, cuando paso el mouse sobre las afirmaciones de "problema", las identifica como constantes.

const int ThisClass::EXAMPLE_CONSTANT 

error expression must have a constant value 

Esto me parece un poco contrario a la intuición. Investigué un poco y encontré un problema similar al de otra persona. Se les dijo que todas las constantes, de hecho, se deben inicializar en 'main' y que esto era una limitación del lenguaje. ¿Es este realmente el caso? No parece probable.

+1

proporcionan el código real que demuestra el problema. Lo que pegaste no es realmente útil. – tenfour

+0

por favor publique el código – Heisenbug

+0

¿Qué compilador está usando? ¿Es realmente C++? – harper

Respuesta

12

Los case declaraciones requieren valor integral que debe ser conocido en tiempo de compilación -tiempo, que es lo que significa constante aquí. Pero los miembros const de una clase no son realmente constante en ese sentido. Ellos son simplemente de solo lectura.

En lugar de campos, puede utilizar enum:

class ThisClass 
{ 
    public: 

     enum Constants 
     { 
      EXAMPLE_CONSTANT = 10, 
      ANOTHER_CONSTANT = 20 
     };  
}; 

Y entonces se puede escribir,

switch(c) 
{ 
     case ThisClass::EXAMPLE_CONSTANT: 
        //code 
        break; 
     case ThisClass::ANOTHER_CONSTANT: 
        //code 
        break; 
}; 
+2

si las constantes no están relacionadas, propongo usar una enumeración sin nombre. –

3

Necesita una constante de tiempo de compilación "real". const en C++ significa solo lectura, y una variable const puede inicializarse igual que int y = 0; const int x = y;, haciendo que x sea una copia de solo lectura del valor y que tenía en el momento de la inicialización.

Con un compilador moderno, puede utilizar enum s o constexpr s para almacenar los miembros (integral) de tiempo de compilación-constness:

class Foo { 
public: 
    static constexpr int x = 0; 
    enum { y = 1 }; 
}; 

int main() { 
    switch (0) { 
    case Foo::x: ; 
    case Foo::y: ; 
    } 
} 
+0

'constexpr' no hace al miembro estático. –

+0

@Martinho: reparado. –

1

Constantes utilizadas en las etiquetas de caso debe ser expresiones constantes integrales. Una expresión constante integral debe satisfacer un conjunto de requisitos mucho más estrictos que el simple hecho de ser un objeto integral declarado como const.

Un miembro de clase no estático no se puede utilizar en una expresión de constante integral, por lo que lo que intenta hacer no se compilará. Un miembro de clase estático, por ejemplo, puede usarse en una expresión de constante integral si su inicializador es "visible" en el punto de uso.

1

Esto es un poco complicado. En C++ const se puede usar para varias cosas, como declarar constantes reales y declarar variables de solo lectura.

Si se declara:

const int x = 0; 

En global, el espacio de nombres, o el ámbito local, es una constante. Puede usarlo cuando se requieren expresiones constantes (como etiquetas de casos o tamaños de matriz). Sin embargo, en el alcance de la clase o como un parámetro de función, es solo una variable de solo lectura.

Además, si se declara en el ámbito de la clase:

static const int x = 0; 

Ésta es también una constante.

+1

Una variable 'const int' declarada en el alcance de la función (es decir, en el ámbito local) y se inicializa con una expresión de constante integral, ella misma forma expresiones constantes integrales en C++. Entonces, en el alcance de la función no es solo una "variable de solo lectura". – AnT

+0

@AndreyT oops, quise decir parámetro de función :) Gracias. –

0

std::map + C++ 11 lambdas solución

Este método permite no constantes, debe dar nos O(1) amortizaron What is the best way to use a HashMap in C++?:

#include <ctime> 
#include <functional> 
#include <unordered_map> 
#include <iostream> 

int main() { 
    int result; 
    int key0 = std::time(NULL) % 3; 
    int key1 = (key0 + 1) % 3; 
    int key2 = (key0 + 2) % 3; 
    std::unordered_map<int,std::function<void()>> m{ 
     {key0, [&](){ result = 0; }}, 
     {key1, [&](){ result = 1; }}, 
     {key2, [&](){ result = 2; }}, 
    }; 
    m[key0](); 
    std::cout << key0 << " " << result << std::endl; 
    m[key1](); 
    std::cout << key1 << " " << result << std::endl; 
    m[key2](); 
    std::cout << key2 << " " << result << std::endl; 
} 

salida posible:

1 0 
2 1 
0 2 

Para uso desde dentro de una clase, no te olvides de construir el stati del mapa como se muestra en: Why switch statement cannot be applied on strings?

Cuestiones relacionadas