Pregunta

Tengo un programa que se necesita para establecer el tipo de un vector como se ejecuta el programa (de acuerdo a un valor en un archivo de configuración).

He intentado hacer esto:

int a = 1

if(a == 1)  vector<int> test(6);
else  vector<unsigned int> test(6);

test.push_back(3);

Pero esto me da:

Error   1   error C2065: 'test' : undeclared identifier

No estoy del todo seguro de por qué, pero creo que esto es debido a que el vector no está realmente decidido en tiempo de compilación, por lo que el compilador no puede trabajar con él mientras compila el resto del código.

Es allí una manera de decidir el tipo de un vector en tiempo de ejecución similar a lo que he intentado de arriba?He tratado de crear una versión fuera de la si y, a continuación, elimine y vuelva a escribir la nueva versión dentro de la SI.Esto, sin embargo, se siente mal y yo no puedo conseguir que funcione de todos modos.gracias.

¿Fue útil?

Solución

La razón por la que no funciona es que estás declarando los vectores dentro del bloque if y else, respectivamente, por lo que quedan fuera de alcance una vez que finaliza el bloque.

  

¿Hay alguna manera de decidir el tipo de vector en tiempo de ejecución similar a lo que he intentado anteriormente?

No, el tipo de una variable debe conocerse en tiempo de compilación. Su única opción es colocar la línea test.push_back(3) así como cualquier código siguiente que acceda a test en el bloque if- y else, o evitar la duplicación de código en una segunda función con plantilla. Esto podría verse así:

template <class T>
do_something_with_test(vector<T>& test) {
    test.push_back(3);
    // work with test
}

void foo() {
    int a = 1

    if(a == 1) {
        vector<int> test(6);
        do_something_with_test(test);
    }
    else {
        vector<unsigned int> test(6);
        do_something_with_test(test);
    }
}

Otros consejos

La razón exacta del error que está recibiendo es algo sutil para un principiante, e involucra el alcance de la variable test que está creando. En pocas palabras, está creando el vector dentro de la instrucción if, pero para el momento en que lo va a usar, ya no existe porque se ha salido del alcance.

He formateado su código entre paréntesis para que este efecto sea más notable. Tenga en cuenta que mi versión es semánticamente equivalente a la suya y dará el mismo error.

if(a == 1)
{
  vector<int> test(6);
}
else
{
  vector<unsigned int> test(6);
}

test.push_back(3);

Dicho esto, lo que estás tratando de hacer parece un poco extraño, y tengo que preguntarme cuál es tu objetivo final. Eso no quiere decir que no haya formas de hacer lo que parece querer hacer, pero necesitaría saber cuáles son sus criterios de éxito antes de poder sugerir un método más apropiado.

No estoy seguro de por qué lo necesita, pero le sugiero que intente usar un vector de unión para resolver su problema, algo como esto

union DataType
{
    int intVal;
    unsigned uintVal;
}
std::vector<DataType> vec;

O probablemente la forma más elegante es usar boost :: variante en lugar de la unión. Quizás si nos brinda más detalles sobre su problema, obtendrá una respuesta mucho mejor.

¡Buena suerte!

Puede echar un vistazo a boost :: any para lograr algo similar.

Establecer el tipo de un vector (también conocido como instanciación de plantilla ) siempre ocurre en tiempo de compilación. Para obtener más aclaraciones, consulte el artículo de Wikipedia sobre Metaprogramación de plantillas .

si realmente necesita un tipo polimórfico, tal vez podría echar un vistazo a la clase boost :: variant o algo similar;
Esto está diseñado para imitar parte del comportamiento de los lenguajes dinámicos dentro de C ++, y generalmente se usa para interactuar con ellos (o implementarlos). podría crear un " vector < Variante & Gt; a " ;, y a.push_back (Variant ((unsigned int) ..). los constructores de valores introducidos necesitan un tipo de tiempo de compilación.

También sería posible crear una clase de variante vectorizada que almacene la información de tipo para toda la colección si espera que los valores sean homogéneos.

pero, es mucho más probable que pueda lograr el resultado final deseado sin dicho mecanismo, reelaborando su programa para evitar las comprobaciones de tipo de tiempo de ejecución (lo que probablemente negaría algunos de los beneficios de usar C ++ en otro idioma en primer lugar) )

Puede escribir las partes dependientes del tipo como plantillas (como se sugirió anteriormente) y seleccionar una ruta de código alternativa basada en la configuración del archivo de configuración marcada & amp; enviado una vez. Este estilo de codificación se vuelve un poco más fácil en c ++ 0x con 'auto' y decltype () también.

El caso específico de los valores sin signo versus con signo implica permitir un bit más que suena inusual o un beneficio marginal en comparación con la complejidad añadida, pero puedo imaginar fácilmente uno que quiera una implementación que pueda cambiar entre flotación de precisión simple y doble, por ejemplo .

Sin embargo, otra opción simple sería hacer una configuración de tiempo de compilación para el tipo (por ejemplo, introducida como una definición desde la configuración de compilación o el archivo MAKE), luego distribuir múltiples versiones de su programa, lo que podría tener sentido en algunas circunstancias. Sin embargo, las plantillas ya sugeridas tienen más probabilidades de ser la opción más útil.

En tu ejemplo, usted tiene instancias independientes de una variable test creado en cada rama de su if instrucción, cada uno de los cuales sale del ámbito de inmediato.Así que cuando el compilador se pone a test.push_back(3); no hay test variable en el ámbito de aplicación, de ahí el error.

Para solucionar tu problema, no se puede luchar contra el sistema de tipo:suponiendo que int y unsigned int son los tipos reales en cuestión que estaría mucho mejor con vector<int> todo, suponiendo que en realidad no necesitan toda la gama de unsigned int.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top