简体   繁体   English

在没有捕获列表的情况下访问lambda中的变量

[英]Accessing variables in lambda without capture list

I wonder why I can use global variables (thanks to Chris Drew for correcting me) in lamdas and why I don't need to capture them: 我想知道为什么我可以在lamda中使用全局变量(感谢Chris Drew纠正了我),为什么我不需要捕获它们:

#include <iostream>
#include <vector>
using namespace std;

size_t i = 0;
vector<int> v = {1,2,3};

int main()
{
    auto lambda = [](){i = v.size();};
    lambda();
    cout << i << endl;

    return EXIT_SUCCESS;
}

In this minimum working example I am accessing the size_t and the vector without capturing them. 在这个最小的工作示例中,我将访问size_t和向量,而不捕获它们。 I would have to if they were declared inside the main-method. 我将不得不在主方法中声明它们。 Why is that so and how can I copy the size_t and the vector? 为什么会这样,如何复制size_t和向量? I tried to use [=] as capture list but it does not copy v and i . 我尝试使用[=]作为捕获列表,但它不复制vi

One way to capture a global variable by value is to use C++14 generalized lambda captures : 一种通过值捕获全局变量的方法是使用C ++ 14 广义lambda捕获

#include <iostream>
#include <vector>

size_t i = 0;
std::vector<int> v = {1,2,3};

int main() {
    auto lambda = [myi = i, myv = v]()mutable{myi = myv.size();};
    lambda();
    std::cout << i << std::endl;
}

Live demo. 现场演示。

In your case i and v are global variable, accessible to the whole TU. 在您的情况下, iv是全局变量,整个TU均可访问。

As you asked how to capture them by value, I think you should be able to capture them using both [=] or listing the variables [i, v] , but this would lead to an error, because they will be read-only and you are assigning to i inside the lambda body. 当您询问如何按值捕获它们时,我认为您应该能够同时使用[=]或列出变量[i, v]来捕获它们,但这将导致错误,因为它们将是只读的,并且您正在lambda体内分配给i

Option 1: 选项1:
capture i by ref and v by value (if that makes sense at all...): 通过ref捕获i并通过值捕获v(如果完全有意义...):

#include <iostream>  
#include <vector>  
using namespace std;
int main() {
    size_t i = 0;
    vector<int> v = {1,2,3};
    auto lambda = [&i,v](){i = v.size();};
    lambda();
    cout << i << endl;

    return EXIT_SUCCESS; }

http://ideone.com/fkn4za http://ideone.com/fkn4za

Option 2: 选项2:
use a mutable lambda and capture both by value (this makes even less sense). 使用可变的lambda并按值捕获两者(这更没有意义)。
Ie see this question on SO . 在SO上看到这个问题
Please note that in this case also i will be captured by value, thus the global i will not be assigned, remaining at value == 0. 请注意,在这种情况下, i也会被值捕获,因此不会分配全局i ,其值保持为== 0。

http://ideone.com/qwlFVv http://ideone.com/qwlFVv

Lambdas have accesses to global variables, and static variables in a class without explicitly capturing them. Lambda可以访问全局变量和类中的静态变量,而无需显式捕获它们。 If it were a local variable, then you program would be ill-formed. 如果它是局部变量,则您的程序将格式错误。

#include <iostream>
#include <vector>
using namespace std;
int main()
{
    size_t i = 0;
    vector<int> v = {1,2,3};
    auto lambda = [](){i = v.size();};   //Error, 
    lambda();
    cout << i << endl;

    return EXIT_SUCCESS;
}

As seen here 这里所见

Same with static variables in a class: 与类中的静态变量相同:

#include <iostream>
#include <vector>
using namespace std;

struct S{
    void touch(){ []{ k = 89; }(); }
    static int getK(){ return k; }
private:
    static int k;
};

int S::k = 0;


int main()
{
    S s;
    std::cout << S::getK() << std::endl;
    s.touch();
    std::cout << S::getK() << std::endl;
}

As seen Here 这里所见

Your lambda is basically converted to a functor, it's the same as : 您的lambda基本上已转换为函子,它与:

#include <iostream>
#include <vector>
using namespace std;

size_t i = 0;
vector<int> v = {1,2,3};

struct lambda
{
  void operator()() { i = v.size(); }
};

int main()
{
    lambda x;
    x();
    cout << i << endl;

    return EXIT_SUCCESS;
}

As you can see, lambda can perfectly access any global variable, it's even in their name, the variable is globally accessible. 如您所见, lambda可以完美地访问任何全局变量,即使以它们的名字命名,该变量也可以全局访问。

If i and v were local to main() then we'd have an issue and we'd have to capture them. 如果iv对于main()是本地的,那么我们将遇到一个问题,我们必须捕获它们。

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

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