2009-05-06 17 views
6

A volte ho bisogno di imparare il tipo di un'espressione mentre si programma in C o C++. A volte c'è un buon IDE o documentazione esistente per aiutarmi, ma a volte no. Spesso mi sento un tale costrutto potrebbe essere utile:Determinazione del tipo di un'espressione

void (*myFunc)(int); 
printf("%s", nameoftype(myFunc)); //"void (*)(int)" 
int i, unsigned int u; 
printf("%s", nameoftype(i+u)); //"unsigned int" 

Ciò è particolarmente vero per C++; pensa agli accessors degli oggetti const: restituiscono un riferimento const o una copia? Pensa ai cast dinamici e alle classi di modelli.

Come posso fare questo? (Ad esempio, impara il tipo di espressione)

Io uso GCC ma, per quanto ne so, non ha un'estensione del genere. Quindi immagino di essere curioso di sapere come le persone risolvono questo problema. (Sia le soluzioni di compilazione che quelle di runtime sono benvenute.)

risposta

1

Cosa stai cercando? Inferenza di tipo automatica o ricerca del tipo in modo da poter dichiarare una variabile in modo corretto manualmente? (le tue risposte sembrano che tu voglia avere il secondo). In questo caso, è consigliabile utilizzare Geordi:

<litb> make type pointer to function taking pointer to array of 10 int returning void 
<geordi> void (*)(int (*)[10]) 

<litb> geordi: { int a = -1; unsigned int b = 0; cout << ETYPE(a + b), ETYPE_DESC(a + b), (a + b); } 
<geordi> rvalue unsigned int, rvalue unsigned integer, 4294967295 

<litb> geordi: << TYPE_DESC(void (*)(int (*)[10])) 
<geordi> pointer to a function taking a pointer to an array of 10 integers and returning nothing 

tipo automatico deduzione al momento non è possibile senza le librerie di supporto come boost.typeof, che utilizzeranno le estensioni del compilatore come __typeof__ per GCC. Il prossimo C++ riceverà auto (con semantica diversa da quella attuale auto) e sarà in grado di farlo, insieme a decltype per ottenere il tipo di espressione.

Se si può vivere con alzarsi dal contesto locale, si può sempre creare un modello di funzione come questa:

template<typename T> void f(T t) { /* ... */ } 
int main() { int a = -1; unsigned int b = 0; f(a + b); } 
+0

Scusa, ho pensato che fosse ovvio che non stavo cercando inferenza di tipo. Anche se non vedo l'ora di vedere qualche nuovo codice C++ 0x sphagetti con variabili automatiche tutto intorno :) - Wow, avevo dimenticato che Geordi poteva fare descrizioni dei tipi. Daremo un'occhiata all'implementazione. Grazie anche per il collegamento KDevelop. Potrebbe essere un'alternativa a Eclipse. – aib

+1

Il link di Geordi è morto - ecco la posizione corrente su github: https://github.com/Eelis/geordi – KarlC

2

C++ ha un operatore typeid;

typeid(expression).name() 

restituirebbe un nome definito dall'implementazione del tipo di espressione. Ahimè, di solito non è leggibile dall'uomo.

+3

Se youare utilizzando g ++ è il nome mangeled. È quindi possibile utilizzare lo strumento della riga di comando 'C++ filt' per demolirlo. –

+0

Ah, non ho mai usato C++ filt. Lo esaminerò, grazie. – aib

+0

Attualmente questo approccio non è raccomandato, e dovrebbe essere considerato in alcuni casi deprecato. La ragione per cui stampa tipo, il tipo di output è macchinoso. Inoltre a volte stampa un tipo non valido! Gli esempi esatti sono chiaramente spiegati nel nuovo "Effective Modern C++", Capitolo 1, elemento 4. – likern

13

A volte mi basta fare:

int ***a = expression; 

e cercare il "< tipo di espressione > non può essere assegnato al puntatore a^3 int" errore. Questa sembra essere la soluzione più portabile.

+1

Alcuni compilatori C più vecchi in realtà lo permetteranno. :-( –

+3

Creo una classe 'FailAssign', quindi provo ad assegnare un'espressione a un'istanza della classe, in questo modo non vengono eseguite conversioni automatiche (anche con errori) –

+2

Hmm, buona idea.Sebbene il mio modo ti consenta di dichiarare un puntatore triplo! Quanto spesso riesci a farlo? :) – aib

1

Prova Boost.Typeof per vedere se si adatta.

+0

Sembra una buona soluzione per l'inferenza di tipo, ma non ho visto una macro che valuta, o una funzione che restituisce una stringa contenente il nome del tipo. Si potrebbe aggiungere uno, però, visto come utilizza le macro centrali REGISTER_(). – aib

Problemi correlati