Domanda

Ho un programma che deve impostare il tipo di vettore mentre il programma viene eseguito (in base a un valore in un file di configurazione).

Ho provato questo:

int a = 1

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

test.push_back(3);

Ma questo mi dà:

Error   1   error C2065: 'test' : undeclared identifier

Non sono del tutto sicuro del perché, ma penso che ciò sia dovuto al fatto che il vettore non viene effettivamente deciso in fase di compilazione, quindi il compilatore non può lavorarci durante la compilazione del resto del codice.

Esiste un modo per decidere il tipo di vettore in fase di esecuzione simile a quello che ho tentato sopra?Ho provato a creare una versione all'esterno di if, quindi eliminarla e riscrivere la nuova versione all'interno di IF.Questo tuttavia sembra sbagliato e non riesco comunque a farlo funzionare.Grazie.

È stato utile?

Soluzione

Il motivo per cui non funziona è che stai dichiarando i vettori all'interno del blocco if e else rispettivamente, quindi escono dall'ambito una volta terminato quel blocco.

  

C'è un modo per decidere il tipo di un vettore in fase di esecuzione simile a quello che ho tentato sopra?

No, il tipo di una variabile deve essere noto al momento della compilazione. L'unica opzione è quella di inserire la riga test.push_back(3) e qualsiasi codice seguente che accede a test nel blocco if- e else, o per evitare la duplicazione del codice in una seconda funzione basata su modelli. Potrebbe apparire così:

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);
    }
}

Altri suggerimenti

Il motivo esatto dell'errore che stai riscontrando è in qualche modo sottile per un principiante e coinvolge l'ambito della variabile test che stai creando. In poche parole, stai creando il vettore all'interno dell'istruzione if, ma quando lo userai, non esiste più perché è uscito dall'ambito.

Ho riformattato il tuo codice tra parentesi per rendere questo effetto più evidente. Nota che la mia versione è semanticamente equivalente alla tua e darà lo stesso errore.

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

test.push_back(3);

Detto questo, quello che stai cercando di fare sembra un po 'strano, e devo chiedermi quale sia il tuo obiettivo finale. Questo non vuol dire che non ci sono modi per fare ciò che sembra voler fare, ma avrei bisogno di sapere quali sono i tuoi criteri di successo prima di poter suggerire un metodo più appropriato.

Non sono sicuro del motivo per cui ne hai bisogno, ma ti suggerisco di provare a utilizzare un vettore di unione per risolvere il tuo problema, qualcosa del genere

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

O probabilmente il modo più elegante è usare boost :: variante invece del sindacato. Forse se ci dai maggiori dettagli sul tuo problema otterrai una risposta molto migliore.

Buona fortuna!

Puoi dare un'occhiata a boost :: any per ottenere qualcosa di simile.

L'impostazione del tipo di un vettore (ovvero istanza di modello ) avviene sempre in fase di compilazione. Per ulteriori chiarimenti, consulta l'articolo di Wikipedia su Metaprogramming dei modelli .

se hai davvero bisogno di un tipo polimorfico, forse potresti dare un'occhiata alla classe boost :: variant o qualcosa di simile;
Questo è progettato per imitare alcuni dei comportamenti dei linguaggi dinamici all'interno del C ++ e di solito viene utilizzato per interfacciarli (o implementarli). potresti creare un " vector < Variante & Gt; a " ;, e a.push_back (Variant ((unsigned int) ..). I costruttori per i valori inviati hanno bisogno del tipo di tempo di compilazione.

Sarebbe anche possibile creare una classe di variante vettorializzata che memorizza le informazioni sul tipo per l'intera raccolta se ci si aspettava che i valori fossero omogenei.

ma, è molto più probabile che tu possa ottenere il risultato finale desiderato senza un tale meccanismo, rielaborando il tuo programma per evitare forse i controlli del tipo di runtime (che molto probabilmente negherebbe alcuni dei vantaggi dell'utilizzo del C ++ su un'altra lingua in primo luogo ).

È possibile scrivere le parti dipendenti dal tipo come modelli (come suggerito sopra) e selezionare un percorso di codice alternativo basato sull'impostazione del file di configurazione selezionata & amp; spedito una volta. Questo stile di codifica diventa leggermente più semplice in c ++ 0x anche con 'auto' e decltype ().

Il caso specifico dei valori non firmati rispetto a quelli firmati implica consentire un altro bit che suona inusuale o di beneficio marginale rispetto alla complessità aggiunta, ma posso facilmente immaginare uno che desidera un'implementazione che può passare da un galleggiante di precisione singolo a doppio, ad esempio .

Ancora un'altra semplice opzione sarebbe quella di fare un'impostazione del tempo di compilazione per il tipo (ad esempio introdotto come una definizione dalle impostazioni di compilazione o makefile), quindi distribuire più versioni del programma, il che potrebbe avere senso in alcune circostanze. Tuttavia, i modelli già suggeriti hanno maggiori probabilità di essere l'opzione più utile.

Nel tuo esempio, hai istanze indipendenti di una variabile test creato in ogni filiale del tuo if dichiarazione, ciascuna delle quali esce immediatamente dall'ambito.Quindi, quando il compilatore arriva a test.push_back(3); Non c'è test variabile nell'ambito, da qui l'errore.

Per risolvere il tuo problema, non puoi combattere il sistema dei tipi:supponendo che int E unsigned int sono i tipi reali in questione che faresti molto meglio a utilizzare vector<int> in tutto, presupponendo che in realtà non sia necessario l'intero intervallo di un int senza segno.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top