2011-03-18 80 views
2

以下代碼編譯正常。C++宏問題(逗號解釋)

#define CMD_MACRO(pp, cmd) \ 
{   \ 
     if (pp)\ 
     { cmd; }  \ 
} 

template<class T> void operate_on(T &data, char c) { 
    data=data+1; 
}; 

int main() { 
    int book=4; 
    char c; 
    CMD_MACRO(book, { 
     operate_on<int>(book, c); 
    }); 
}; 

注意,在我的代碼中的實際宏是比較複雜的,我已經給了一個簡化版本,它可能沒有太大的邏輯意義現在

,如果我在函數中添加另一個模板參數它給出編譯錯誤(問題代碼註釋解釋):

template<class T, bool b> void operate_on(T &data, char c) { 
    data=data+1; 
}; 
int main() { 
     int book=4; 
     char c; 
     CMD_MACRO(book, { 
      operate_on<int, false>(book, c); /* here the "," between int and 
        false is being treated 
        as separating arguments to CMD_MACRO, 
        instead being part of 'cmd'. Thats strange 
        because the comma separating book and c is 
        treated fine as part of 'cmd'. */ 
     }); 
}; 


test.cpp:18:6: error: macro "CMD_MACRO" passed 3 arguments, but takes just 2 
test.cpp: In function 'int main()': 
test.cpp:16: error: 'CMD_MACRO' was not declared in this scope 

如何解決這個問題(我需要額外的模板參數添加到現有的代碼和我得到這樣的錯誤)。

+1

一個較新的問題有一些優秀的答案:http://stackoverflow.com/questions/13842468/comma-in-c-c-macro/13842784#13842784 – jjrv 2014-07-17 05:36:52

回答

6

你試過了嗎:(operate_on<int, false>(book, c));? (注意表達式附近的括號)。

我相信預處理器對C++模板一無所知,因此將<>視爲任何舊的令牌。沒有額外的括號,它將operate_on<int作爲一個參數,而false>(book, c)作爲另一個參數。

+1

沒錯。預處理器知道'()'而不是'[]'或'{}'或'<>'。 – aschepler 2011-03-18 04:33:07

+0

非常恰當,預處理器在分析時並不像語言那麼聰明。我經常不得不爲宏參數添加額外的括號。 – 2011-03-18 04:34:51

+0

很好..它的工作原理..甚至從來沒有知道額外的「(」周圍的代碼作爲「{」和是有效的語法 – jeetu 2011-03-18 04:38:03