C++ Lambda表达式不能捕获当前作用域的枚举,可以捕获另一个Labmda表达式,前者不必为后者传递捕获后者的捕获列表

C++ Lambda表达式不能捕获当前作用域的枚举,枚举在C++中也算是个类型,它不是变量,只有变量才可以被捕获,可以捕获另一个Labmda表达式,前者不必为后者传递捕获后者的捕获列表

另外,C++ Lambda表达式不能引用捕获当前方法|函数中的静态变量(是出于什么原因?),但定义一个非静态的引用变量引用那个静态变量,然后把这个引用传引用给Lambda表达式就可以“间接”引用静态变量了,绕过Lambda表达式不能捕获静态变量的障碍,

#include <iostream>
int main(int argc, char *argv[]){
    enum myenum{
        heihei=1,
        haha,
        halo
    };
    int a(3),b(1);
    static int c(5);
    auto Lambda1=[a,b]()->int{return a+b;};
    auto Lambda2=[a,b]()->int{return a-b;};
    auto Lambda3=[Lambda1,Lambda2,&c]()->int{return Lambda1()+Lambda2()+c;};
    std::cout<<Lambda3()<<"\n";
    std::cin>>a;
    return 0;
}
> Executing task: /usr/bin/clang++ -std=c++17 -stdlib=libc++ -g /Users/haypin/VScode/cpptest/Lambda.cpp -o /Users/haypin/VScode/cpptest/Lambda <

/Users/haypin/VScode/cpptest/Lambda.cpp:12:36: error: 'c' cannot be captured because it does not have automatic storage
      duration
    auto Lambda3=[Lambda1,Lambda2,&c]()->int{return Lambda1()+Lambda2()+c;};
                                   ^
/Users/haypin/VScode/cpptest/Lambda.cpp:9:16: note: 'c' declared here
    static int c(5);
               ^
1 error generated.
The terminal process "/bin/bash '-c', '/usr/bin/clang++ -std=c++17 -stdlib=libc++ -g /Users/haypin/VScode/cpptest/Lambda.cpp -o /Users/haypin/VScode/cpptest/Lambda'" terminated with exit code: 1.

Terminal will be reused by tasks, press any key to close it.


error: 'c' cannot be captured because it does not have automatic storage

定义一个引用d引用静态变量c,然后传引用给Lambda表达式就可以了,使Lambda表达式“间接引用“了静态变量:

#include <iostream>
int main(int argc, char *argv[]){
    enum myenum{
        heihei=1,
        haha,
        halo
    };
    int a(3),b(1);
    static int c(14);
    int &d=c;
    auto Lambda1=[a,b]()->int{return a+b;};
    auto Lambda2=[a,b]()->int{return a-b;};
    auto Lambda3=[Lambda1,Lambda2,/*&c*/&d]()->int{return Lambda1()+Lambda2()+d;};
    int nRes=Lambda3();
    std::cout<<nRes<<"\n";
    std::cin>>a;
    return 0;
}

 

.vscode/tasks.json:

{
	"version": "2.0.0",
	"tasks": [
		{
			"type": "shell",
			"label": "C/C++: clang++ build active file",
			"command": "/usr/bin/clang++",
			"args": [
				"-std=c++17",
				"-stdlib=libc++",
				"-g",
				"${file}",
				"-o",
				"${fileDirname}/${fileBasenameNoExtension}"
			],
			"options": {
				"cwd": "${workspaceFolder}"
			},
			"problemMatcher": [
				"$gcc"
			],
			"group": "build"
		}
	]
}

.vscode/launch.json:

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "type": "lldb",
            "request": "launch",
            "name": "Debug",
            "program": "${fileDirname}/${fileBasenameNoExtension}",
            "args": [],
            "cwd": "${workspaceFolder}",
            "console":"integratedTerminal",
            "preLaunchTask": "C/C++: clang++ build active file",
        }
    ]
}

mac10.15.6上VScode的clang++编译器默认支持的C++版本应该是低于C++11的,编译任务配置tasks.json中如果不给"-std=c++17"和"-stdlib=libc++"参数在编译时会指出auto类型说明符是C++11扩展,并且捕获列表还没编译成功:

参见VSCode官网文档:https://code.visualstudio.com/docs/cpp/config-clang-mac

补充:C++的Lambda表达式的引用列表捕获的变量或常量,是Lambda表达式定义处上溯作用域链名字查找的,在Lambda表达式执行时进行实参->形参传值或直接使用引用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Lambda 表达式中,捕获列表用于指定要捕获的外部变量。捕获列表可以包含以下 3 种方式: 1. 捕获捕获值可以通过在捕获列表中指定变量的方式来完成。在捕获值时,Lambda 表达式会在创建时将指定的变量复制一份,并在函数体中使用这份副本。例如: ```c++ int x = 1; auto func = [x]() { std::cout << x << std::endl; }; ``` 在上面的代码中,Lambda 表达式通过捕获值的方式来捕获变量 x。在 Lambda 表达式中使用的变量 x 是一个拷贝,对其进行修改不会影响原有的变量 x。 2. 捕获引用 捕获引用可以通过在捕获列表中指定变量的方式来完成。在捕获引用时,Lambda 表达式会在创建时将指定的变量的引用传递给函数体。例如: ```c++ int x = 1; auto func = [&x]() { std::cout << x << std::endl; }; ``` 在上面的代码中,Lambda 表达式通过捕获引用的方式来捕获变量 x。在 Lambda 表达式中使用的变量 x 是原有变量的引用,对其进行修改会影响原有的变量 x。 3. 捕获列表 捕获列表可以通过在捕获列表中指定变量的方式来完成。在捕获列表中,可以同时指定多个变量,并且可以使用值或引用的方式进行捕获。例如: ```c++ int x = 1, y = 2; auto func = [x, &y]() { std::cout << x << " " << y << std::endl; }; ``` 在上面的代码中,Lambda 表达式通过捕获列表的方式来捕获变量 x 和 y。变量 x 是以值的方式进行捕获的,变量 y 是以引用的方式进行捕获的。 需要注意的是,在 Lambda 表达式捕获变量时,要考虑变量的生命周期。如果捕获一个局部变量,而且这个局部变量已经超出了作用域,那么在 Lambda 表达式执行时可能会引发未定义的行为。为了避免这种情况,可以使用捕获值或捕获引用的方式来避免变量超出作用域的问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值