Why doesn't the commented out line in the following program compile?
#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;
}
The preprocessor does not know about {}
initialisation. It sees the comma and thinks that's the start of a new macro argument. And then the next one. Only brackets ()
are things that it knows about.
[C++11: 16.3/11]:
The sequence of preprocessing tokens bounded by the outside-most matching parentheses forms the list of arguments for the function-like macro. The individual arguments within the list are separated by comma preprocessing tokens, but comma preprocessing tokens between matching inner parentheses do not separate arguments. [..]
A macro is not a function. It interprets your input vector<int>{1,2,3}
as 3 inputs, which are vector<int>{1
,2
and 3}
. You can change this by making it an expression (vector<int>{1,2,3})
(as you already did).
Everything in parantheses is an expression and .vector<int>(...)
is a (*special member-)function so the preprocessor sees it as one expression
Another workaround is to transform your MACRO into a variadic MACRO
#define F1(...) 1
Or in a more general case; turn:
#define M(a) a
into this:
#define M(...) __VA_ARGS__
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With