2015-02-17 6 views
28

Ich wusste, dass, wenn wir nicht Platz nach dem Schließen von spitzen Klammern in einer Variablendeklaration stellen, C++ den folgenden Fehler auslöst.Verhalten von # define Makroexpansion in C++

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

Aber der Fehler kommt nicht, wenn ich in diesem Code #define wie verwenden. Kann mir das jemand erklären?

Ich denke, #define ist nur eine Makro-Erweiterung und funktioniert wie Suchen-Ersetzen, so beide Möglichkeiten, Variablen hier zu deklarieren sollte identisch sein.

Auch dieser Fehler tritt nicht auf, wenn ich es mit C++ 11 kompiliere.

#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 wurde '' 'durch eine spezielle Regel gültig, weil der Platzbedarf so ein Ärgernis war. –

+0

Sie möchten wissen, warum das Makro funktioniert? Ich habe hier keine Frage gesehen. – Aitch

+1

Ja Ich möchte wissen, warum das Makro funktioniert – Jignesh

Antwort

36

Makroexpansion erfolgt nach Tokenisierung; Es ersetzt nicht Text, sondern Tokenfolgen.

Dies bedeutet, dass die Erweiterung vi mit dem Makro ein > Token ergibt, das von dem nach dem Makroaufruf getrennten Token getrennt ist. In jedem Fall findet die Tokenisierung nur ein einziges > Zeichen, also das resultierende Token.

Ohne ein Makro bedeutete die "gierige" Tokenisierungsregel, dass die zwei aufeinanderfolgenden Zeichen als ein einziges Token behandelt wurden, bis C++ 11 eine spezielle Regel für diesen Fall hinzufügte.

+8

Um dies deutlicher zu sehen, betrachte '#define plusi + i'. Sie können jetzt schreiben: int i = 0; std :: cout << + plusi'. Sagen Sie voraus, was passiert und versuchen Sie es dann. – MSalters

+2

@MSalters OTOH, jeder, der das in Produktion bringt, muss entlassen werden –

+0

Dies ist ein wenig kontraintuitiv, wenn man bedenkt, dass es ein separates Präprozessorprogramm, 'cpp', gibt, das reinen Text ausgeben wird. Ich hätte angenommen, dass das explizite Preprocessing und das anschließende Compilieren dasselbe wäre, als würde der Compiler selbst die Vorverarbeitung durchführen. – Szabolcs