2012-07-03 15 views
56

In C++, come si trova il tipo di una variabile?Come ottengo il tipo di una variabile?

+3

Possibile duplicato di http://stackoverflow.com/questions/81870/print-variable-type-in-c – theharshest

+4

cout << typeid (variabile) .name() << endl; – SRN

+0

Usa la ricerca o google :) http://stackoverflow.com/questions/81870/print-variable-type-in-c Theharshest è veloce: D – Kariboo

risposta

71

È possibile utilizzare the typeid operator:

#include <typeinfo> 
... 
cout << typeid(variable).name() << endl; 
+4

Ho 'int a = 5;' e 'typeid (a) .name()' e restituisce 'i' ... – 0x499602D2

+12

@David - Quindi' i' significa intero sul tuo compilatore. I nomi restituiti non sono specificati dallo standard. –

+6

Quando lo uso sul vettore restituisce St6vectorIiSaIiEE. WTF? –

5

Se si dispone di una variabile

int k; 

È possibile ottenere il tipo tramite

cout << typeid(k).name() << endl; 

Vedere questo thread su SO: Similar question

0
#include <typeinfo> 

... 
string s = typeid(YourClass).name() 
9

In genere, voler trovare il tipo di una variabile in C++ è la domanda sbagliata. Tende ad essere qualcosa che porti avanti da linguaggi procedurali come ad esempio C o Pascal.

Se si desidera codificare comportamenti diversi a seconda del tipo, provare ad apprendere a es. function overloading e object inheritance. Questo non ha senso immediato nel tuo primo giorno di C++, ma continua a farlo.

5

La differenza principale tra C++ e Javascript è che C++ è un linguaggio tipizzato staticamente, wile javascript è dinamico.

Nei linguaggi tipizzati dinamici una variabile può contenere qualsiasi cosa, e il suo tipo è dato dal valore che tiene, momento per momento. In linguaggi tipizzati statici, il tipo di variabile è dichiarato e non può essere modificato.

Possono esserci dispatch dinamici e composizione di oggetti e sottotipizzazione (ereditarietà e funzioni virtuali) nonché dispostivi statici e superattivi (tramite modello CRTP), ma in ogni caso il tipo di variabile deve essere noto al compilatore.

Se sei nella posizione di non sapere cosa sia o potrebbe essere, è perché hai progettato qualcosa in quanto il linguaggio ha un sistema di tipi dinamico.

Se è il caso, è meglio ripensare il tuo design, dato che sta entrando in una terra non naturale per la lingua che stai usando (più come andare in autostrada con un bruco o in acqua con un auto)

+0

Se C++ ha il cambiamento dinamico, allora penso che sarebbe bello e typeof e parseInt, anche le funzioni parseFloat saranno utili ma non lo faccio sai perché i produttori di C++ lo rendono troppo difficile, ad esempio! chi dice che è buono a scrivere cout << "String" – Waqas

+0

determinazione è meglio !!!! #include string str ("1912"); int strtointval; stringstream (str) >> strtointval; – Waqas

+0

@Waqas Uh, cosa? Le persone che dicono che è meglio sono le persone che definiscono la lingua, e IMO hanno praticamente l'ultima parola in ogni cosa a che fare con esso - buone pratiche di codifica, per esempio. Potresti riformulare quel commento in modo che abbia più senso? –

1

Credo di avere un caso d'uso valido per l'uso di typeid(), allo stesso modo in cui è valido usare sizeof(). Per una funzione template, ho bisogno di un caso speciale del codice basato sulla variabile template, in modo da offrire la massima funzionalità e flessibilità.

È molto più compatto e manutenibile rispetto all'uso del polimorfismo, per creare un'istanza della funzione per ogni tipo supportato. Anche in questo caso potrei usare questo trucco per scrivere il corpo della funzione una sola volta:

Si noti che poiché il codice utilizza i modelli, l'istruzione di seguito riportata dovrebbe risolversi staticamente in un solo blocco di codice, ottimizzando tutti i falsi casi , PER QUANTO NE SO.

Considera questo esempio, dove potremmo dover gestire una conversione se T è di un tipo contro un altro. Lo uso per la specializzazione di classe per accedere all'hardware in cui l'hardware utilizzerà il tipo myClassA o myClassB. In caso di mancata corrispondenza, ho bisogno di passare il tempo a convertire i dati.

switch ((typeid(T)) { 
    case typeid(myClassA): 
    // handle that case 
    break; 
    case typeid(myClassB): 
    // handle that case 
    break; 
    case typeid(uint32_t): 
    // handle that case 
    break; 
    default: 
    // handle that case 
} 
+1

TipoId: Non ero in grado di usare typeid() su Arduino. Anche typeid() è un controllo * runtime *, non richiede tempo di compilazione, quindi non può essere utilizzato per generare codice ottimizzato. –

+1

Sì, no, questo non fa quello che pensavi. 'typeid' semplicemente non può essere un controllo statico, in fase di compilazione - per definizione - quindi questo non facilita alcuna ottimizzazione. 'Per una funzione template, ho bisogno di un caso speciale del codice basato sulla variabile template 'Giusto, quindi quello che vuoi veramente è il polimorfismo statico tramite l'idioma CRTP. Questo è esattamente ciò che realizza. –

6

Per l'inserimento C++ statico 11 introdotto decltype che è piuttosto utile in alcuni scenari.

0

Non sono sicuro che la mia risposta sarebbe di aiuto.

La risposta breve è che non è necessario/conoscere il tipo di variabile per utilizzarla.

Se è necessario assegnare un tipo a una variabile statica, è possibile utilizzare semplicemente Auto.

Nel caso più sofisticato in cui si desidera utilizzare "auto" in una classe o in una struttura, suggerirei di utilizzare il modello con decltype.

Per esempio, diciamo che si sta utilizzando biblioteca di qualcun altro e ha una variabile chiamata "unknown_var" e si vorrebbe mettere in un vettore o di una struttura, si può assolutamente fare questo:

template <typename T> 
struct my_struct { 
    int some_field; 
    T my_data; 
}; 
vector<decltype(unknown_var)> complex_vector; 
vector<my_struct<decltype(unknown_var)> > simple_vector 

Speranza questo aiuta.

EDIT: Per buona misura, ecco il caso più complesso che possa essere pensato: avere una variabile globale di tipo sconosciuto. In questo caso avresti bisogno di C++ 14 e di template variable.

Qualcosa di simile a questo:

template<typename T> vector<T> global_var; 

void random_func (auto unknown_var) { 
    global_var<decltype(unknown_var)>.push_back(unknown_var); 
} 

E 'ancora un po' noioso, ma è il più vicino si può arrivare a Senza tipo lingue. Assicurati che ogni volta che fai riferimento alla variabile del modello, inserisca sempre le specifiche del modello.

Problemi correlati