c ++宏和lambda捕获

时间:2018-04-13 12:49:36

标签: c++ lambda macros capture

当我在具有多个捕获的宏中使用lambda时,我遇到其中一个错误(Visual Studio 2017)
Error C2143 syntax error: missing ']' before ';'
Error C2958 the left bracket '['

如何避免此错误?

代码示例:

#include <functional>
#include <iostream>

#define MYMACRO(lambda) lambda

int main()
{
    int a = 13;
    int b = 37;
    auto lambda = MYMACRO([a, b]() { std::cout << a << b << std::endl; });
    lambda();
    return 0;
}

2 个答案:

答案 0 :(得分:3)

GCC提供了一个稍微友好的错误消息:

  

10:73:错误:宏“MYMACRO”传递了2个参数,但只需1个

lambda声明中的逗号被解释为对宏的分隔参数。您需要将表达式括在括号中:

#include <functional>
#include <iostream>

#define MYMACRO(lambda) lambda

int main()
{
    int a = 13;
    int b = 37;
    auto lambda = MYMACRO(([a, b]() { std::cout << a << b << std::endl; }));
    lambda();
    return 0;
}

Visual Studio会发出警告,然后忽略虚假的宏参数,因此您的代码等同于:

auto lambda = MYMACRO([a);

这使得错误消息更容易理解。见https://docs.microsoft.com/en-gb/cpp/error-messages/compiler-warnings/compiler-warning-level-1-c4002

答案 1 :(得分:1)

正如其他地方所述,实际的错误是MYMACRO只写了一个参数。除非用括号或引号括起来,否则逗号用于描述宏调用的单独参数。

lambda在捕获括号中可能有多个逗号,因此如果您希望保留调用语法与程序中的相同,MYMACRO实际上需要能够处理变量参数。这是可能的,因为C ++ 11增加了对可变参数宏的支持。

Visual Studio 2017支持可变参数宏语法。因此,您可以将宏更改为:

#define MYMACRO(...) __VA_ARGS__

请注意,变量参数只能出现在宏参数规范的末尾。