Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ macro with lambda argument using 2+ captured elements generates error

Tags:

c++

lambda

macros

foo(const std::function<void()>& functor) {
    ....
}

#define MACRO_EXAMPLE(functor) foo(functor)

int main() {
    int i = 0, j = 0;
    MACRO_EXAMPLE([i](){}); // works fine
    MACRO_EXAMPLE([i, j](){}); // error: macro "MACRO_EXAMPLE" passed 2 arguments, but takes just 1
  });
}

Why? How to make that a macro understands lambdas?

like image 274
fhdnsYa Avatar asked Oct 08 '15 12:10

fhdnsYa


2 Answers

Add one more round of parenthesis:

MACRO_EXAMPLE(([i, j](){}));
//            ^          ^

Otherwise the part before , is interpreted as macro's first parameter, and the part after , is interpreted as the macro's second parameter.

like image 128
SingerOfTheFall Avatar answered Oct 13 '22 14:10

SingerOfTheFall


As an alternative to @SingerofTheFall's answer (which fixes the problem when invoking the macro), you can also fix the problem in the macro itself, by making it variadic:

#define MACRO_EXAMPLE(...) foo(__VA_ARGS__)

This works by allowing the preprocessor to parse the lambda at , tokens into multiple arguments, but then uses all of these arguments and the separating commas again, so the net effect is what you want.

like image 42
Angew is no longer proud of SO Avatar answered Oct 13 '22 13:10

Angew is no longer proud of SO