C++ 宏和 lambda 捕获
c++ macro and lambda 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;
}
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://learn.microsoft.com/en-gb/cpp/error-messages/compiler-warnings/compiler-warning-level-1-c4002
正如其他地方所指出的,实际的错误是编写的MYMACRO
只需要一个参数。除非用括号或引号括起来,否则逗号用于描述宏调用的单独参数。
一个 lambda 在捕获括号中可能有多个逗号,因此如果你想让调用语法与程序中的语法相同,MYMACRO
实际上需要能够处理变量参数。从 C++11 开始,这是可能的,它增加了对可变参数宏的支持。
Visual Studio 2017 支持可变参数宏语法。因此,您可以将宏更改为:
#define MYMACRO(...) __VA_ARGS__
请注意,变量参数只能出现在宏参数规范的末尾。
相关文章:
- 捕获lambda中的std::数组
- 为什么捕获 lambda 不捕获变量?
- 获取具有静态局部变量的绑定/推断捕获 lambda 的函数指针
- 无法通过引用捕获 lambda 中的成员变量
- 无法捕获 lambda 中的静态变量
- 模板函数中的无捕获 lambda 是否具有多个二进制实现?
- 捕获 lambda 函数C++成员变量
- 函数和非捕获 lambda 之间的区别
- 为什么通过复制捕获 lambda 具有与外部变量相同的地址
- 是否有一种方法可以编写此短片而不捕获lambda变量
- 初始化在三元运算符中捕获 lambda
- C++在虚拟方法中使用捕获 lambda
- 内联和constexpr在标头中无捕获lambda有什么区别
- 在编译时获取捕获 lambda 的类型
- 如何捕获 Lambda 标识符
- 如果我使用 std::function 来捕获 lambda,我应该担心它被解除分配吗?
- 无法从通用参考中捕获lambda中的参考
- VC 15调用错误的复制构造函数以捕获lambda
- 将捕获 lambda 作为函数指针传递
- C++ 通过引用捕获 Lambda