2015-05-21 14 views
15

Dlaczego nie skomentowano wiersza komentarza w poniższym programie?Przekazywanie listy inicjalizacyjnej do makra

#include <iostream> 
#include <vector> 
using namespace std; 

#define F1(a) 1 

int F2(vector<int>) { return 2; } 

int main() { 
    vector<int> v; 
    v = vector<int>{1,2,3}; 

    cout << F1(v) << endl; 
    //The following line doesn't compile. The error is: 
    //error: macro "F" passed 3 arguments, but takes just 1 
    //cout << F1(vector<int>{1,2,3}) << endl; // <- error! 
    cout << F1(vector<int>({1,2,3})) << endl; 
    cout << F1((vector<int>{1,2,3})) << endl; 

    cout << F2(v) << endl; 
    //The following line compiles fine 
    cout << F2(vector<int>{1,2,3}) << endl; 
    cout << F2(vector<int>({1,2,3})) << endl; 
    cout << F2((vector<int>{1,2,3})) << endl; 

    return 0; 
} 

Odpowiedz

13

Preprocesor nie wie o {} inicjalizacji. Widzi przecinek i myśli, że to początek nowej argumentacji makro. A potem następny. Tylko nawiasy () są rzeczami, o których wie.

[C++11: 16.3/11]: Sekwencja żetonów preprocesingu ograniczona przez najbardziej dopasowane nawiasy tworzą listę argumentów dla makra funkcyjnego. Poszczególne argumenty na liście są oddzielone przez tokeny preprocesingu przecinkowego, ale tokeny preprocesingu przecinków pomiędzy dopasowanymi nawiasami wewnętrznymi nie rozdzielają argumentów. [..]

+2

Sieć [ Dokumentacja online GCC] (https: //gcc.gnu.o rg/onlinedocs/cpp/Macro-Arguments.html) ma ładny przykład i wyjaśnienie. –

8

makro jest funkcją. Interpretuje on twoje wejście vector<int>{1,2,3} jako 3 wejścia, które są vector<int>{1, 2 i 3}. Możesz to zmienić, czyniąc go wyrażeniem (vector<int>{1,2,3}) (jak już zrobiłeś).

Wszystko w parissheses to wyrażenie i vector<int>(...) jest funkcją (* special member-), więc preprocesor widzi to jako jedno wyrażenie.

+1

Zabawny, przysięgam, że już to powiedziałem !! ('vector (...)' nie jest funkcją.) –

+0

@ Light Dammit - byłeś trochę szybszy: P Poprawiłem to. Czy to teraz? – Otomo

+1

Still, 'vector (...)' tutaj _nie_ jest wywołaniem funkcji. Tak, wiem, że wygląda na to, że dzwonisz do konstruktora. –

3

Innym rozwiązaniem jest przekształcić swoje makro w o zmiennej liczbie argumentów makro

#define F1(...) 1 

Lub, w bardziej ogólnym przypadku:

#define M(a) a 

w

#define M(...) __VA_ARGS__ 
Powiązane problemy