简体   繁体   English

C ++宏和Lambda捕获

[英]c++ macro and lambda capture

When I use a lambda in a macro with multiple captures, I encounter one of these errors (Visual Studio 2017) : 当我在具有多个捕获的宏中使用lambda时,遇到以下错误之一(Visual Studio 2017)
Error C2143 syntax error: missing ']' before ';'
Error C2958 the left bracket '['

How can I avoid this error? 如何避免此错误?

Code example : 代码示例:

#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;
}

GCC gives a slightly more friendly error message: GCC给出了更友好的错误消息:

10:73: error: macro "MYMACRO" passed 2 arguments, but takes just 1 10:73:错误:宏“ MYMACRO”传递了2个参数,但只接受了1个

The commas in your lambda declaration are being interpreted as delimiting arguments to the macro. 您的lambda声明中的逗号被解释为宏的定界参数。 You need to wrap the expression in brackets: 您需要将表达式包装在方括号中:

#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 raises a warning then ignores spurious macro arguments so your code is equivalent to: Visual Studio发出警告,然后忽略虚假的宏参数,因此您的代码等效于:

auto lambda = MYMACRO([a);

Which makes the error message more understandable. 这使错误消息更易于理解。 See https://docs.microsoft.com/en-gb/cpp/error-messages/compiler-warnings/compiler-warning-level-1-c4002 请参阅https://docs.microsoft.com/zh-CN/cpp/error-messages/compiler-warnings/compiler-warning-level-1-c4002

As noted elsewhere, the actual bug is that MYMACRO as written only expects a single argument. 如其他地方所指出的那样,实际的错误是MYMACRO在编写时仅期望一个参数。 Unless enclosed by parentheses or quotes, commas are used to delineate separate arguments to a macro invocation. 除非用括号或引号引起来,否则逗号用于描述宏调用的单独参数。

A lambda may have multiple commas in the capture brackets, so MYMACRO actually needs to be able to handle variable arguments if you want to leave the invocation syntax the same as you have in your program. Lambda可能在捕获括号中带有多个逗号,因此,如果要使调用语法与程序中的语法相同, MYMACRO实际上需要能够处理变量参数。 This is possible since C++11, which added support for variadic macros. 从C ++ 11开始,这是可能的,它增加了对可变参数宏的支持。

Visual Studio 2017 supports the variadic macro syntax. Visual Studio 2017支持可变参数宏语法。 So, you could change your macro to be: 因此,您可以将宏更改为:

#define MYMACRO(...) __VA_ARGS__

Note that the variable arguments can only appear at the end of the macro arguments specification. 请注意,变量参数只能出现在宏参数规范的末尾。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM