为什么以下程序中的注释掉的行没有编译?
#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;
}
答案 0 :(得分:14)
预处理器不知道{}
初始化。它看到逗号并认为这是一个新的宏参数的开始。然后是下一个。只有括号()
是它所知道的东西。
[C++11: 16.3/11]:
由最外部匹配括号限定的预处理标记序列形成类函数宏的参数列表。列表中的各个参数由逗号预处理标记分隔,但匹配内部括号之间的逗号预处理标记不会分隔参数。 [..]
答案 1 :(得分:9)
宏不是一个功能。它会将您的输入vector<int>{1,2,3}
解释为3个输入,即vector<int>{1
,2
和3}
。您可以通过将其设为表达式(vector<int>{1,2,3})
(就像您已经做过的那样)来更改它。
parantheses中的所有内容都是表达式,而。vector<int>(...)
是一个(*特殊成员)函数,因此预处理器将其视为一个表达式
答案 2 :(得分:3)
另一种解决方法是将宏转换为可变参数宏
#define F1(...) 1
或者,在更一般的情况下:
#define M(a) a
到
#define M(...) __VA_ARGS__