2015-02-17 31 views
28

Sapevo che se non mettiamo spazio dopo aver chiuso le parentesi angolari in una dichiarazione di variabile, C++ genera il seguente errore.Comportamento dell'estensione della macro #define in C++

‘>>’ should be ‘> >’ within a nested template argument list

Ma l'errore non viene se uso #define come in questo codice. Qualcuno può spiegarmi questo?

Penso che #define sia solo una macro espansione e funzioni come find-replace, quindi entrambi i metodi di dichiarazione della variabile qui dovrebbero essere identici.

Anche questo errore non si verifica se lo compilo con C++ 11.

#include <bits/stdc++.h> 
using namespace std; 

#define vi vector<int> 

int main(){ 
    //Doesn't work, compile error 
    vector<vector<int>> v; 

    //Works 
    vector<vi> vv; 
} 
+15

In C++ 11 '>>' è diventato valido, tramite una regola speciale, perché il fabbisogno di spazio era un tale fastidio. –

+0

Vuoi sapere, perché la macro funziona? Non ho visto una domanda qui. – Aitch

+1

sì, voglio sapere perché la macro funziona – Jignesh

risposta

36

L'espansione della macro avviene dopo la tokenizzazione; non sostituisce il testo, ma le sequenze di token.

Ciò significa che, con la macro, l'espansione di vi fornisce un token >, separato da quello successivo alla chiamata di macro. In ogni caso, la tokenizzazione trova solo un singolo carattere >, quindi questo è il token risultante.

Senza una macro, la regola di tokenizzazione "avido" significava che i due caratteri consecutivi venivano considerati come un singolo token >>, fino a quando C++ 11 non ha aggiunto una regola speciale per questo caso.

+8

Per vedere questo più chiaramente, si consideri '#define plusi + i'. Ora puoi scrivere 'int i = 0; std :: cout << + plusi'. Prevedi cosa succede e poi prova. – MSalters

+2

@MSalters OTOH, chiunque lo metta in produzione deve essere licenziato –

+0

Questo è un po 'poco intuitivo considerando che esiste un programma separato per il preprocessore, 'cpp', che emetterà testo in chiaro. Avrei dato per scontato che la preprocessazione esplicita, quindi la compilazione in seguito, sarebbe la stessa cosa che consentire al compilatore stesso di effettuare la pre-elaborazione. – Szabolcs