在lambda中,如何通过值捕获引用 [英] In a lambda, how reference is being captured by value

查看:117
本文介绍了在lambda中,如何通过值捕获引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果引用类型的变量是在lambda中按值捕获的,那么它是按引用还是按值捕获的?

有问题的小样本:

#include <iostream>

struct Test {
  int a;
};

void testFunc(const Test &test) {
  auto a = [=] {
    // does 'test' is being passed to closure object with copy
    // or by reference?
    return test.a;
  } ();
  std::cout << a;
}

int main() {
  Test test{1};
  testFunc(test);
}

解决方案

按值.编译示例:

class C
{
public:
    C()
    {
        i = 0;
    }

    C(const C & source)
    {
        std::cout << "Copy ctor called\n";
        i = source.i;
    }

    int i;
};

void test(C & c)
{
    c.i = 20;

    auto lambda = [=]() mutable {

        c.i = 55;
    };
    lambda();

    std::cout << c.i << "\n";
}

int main(int argc, char * argv[])
{
    C c;
    test(c);

    getchar();
}

结果:

Copy ctor called
20

我想这是C ++标准的这一段适用:

5.1.2 Lambda表达式

(...) 14.如果一个实体是通过 copy 捕获的,则它是隐式捕获的,而 capture-default 是=,或者是显式捕获的 使用不包含&的捕获来捕获.对于通过副本捕获的每个实体,一个未命名的非静态 数据成员在闭包类型中声明.这些成员的声明顺序未指定. 如果该数据成员的类型不是一个实体,则该类型的数据成员是相应捕获的实体的类型. 引用对象,或引用类型. [注意:如果捕获的实体是对 函数,相应的数据成员也是对函数的引用. — 尾注]

这实际上是有道理的-如果局部变量是通过值传递的,而参数是通过引用传递的"acts"作为函数中的局部变量,那么为什么要通过引用而不是值传递呢?

If the variable of reference-type is being captured in a lambda by value, is it being captured by reference or by value?

Small sample with question:

#include <iostream>

struct Test {
  int a;
};

void testFunc(const Test &test) {
  auto a = [=] {
    // does 'test' is being passed to closure object with copy
    // or by reference?
    return test.a;
  } ();
  std::cout << a;
}

int main() {
  Test test{1};
  testFunc(test);
}

解决方案

By value. Compilable example:

class C
{
public:
    C()
    {
        i = 0;
    }

    C(const C & source)
    {
        std::cout << "Copy ctor called\n";
        i = source.i;
    }

    int i;
};

void test(C & c)
{
    c.i = 20;

    auto lambda = [=]() mutable {

        c.i = 55;
    };
    lambda();

    std::cout << c.i << "\n";
}

int main(int argc, char * argv[])
{
    C c;
    test(c);

    getchar();
}

Result:

Copy ctor called
20

I guess, that this paragraph of the C++ standard applies:

5.1.2 Lambda expressions

(...) 14. An entity is captured by copy if it is implicitly captured and the capture-default is = or if it is explicitly captured with a capture that does not include an &. For each entity captured by copy, an unnamed nonstatic data member is declared in the closure type. The declaration order of these members is unspecified. The type of such a data member is the type of the corresponding captured entity if the entity is not a reference to an object, or the referenced type otherwise. [ Note: If the captured entity is a reference to a function, the corresponding data member is also a reference to a function. —end note]

That actually makes sense - if local variables are passed by value and parameter passed by reference "acts" as a local variable in function, why would it be passed by reference instead of value?

这篇关于在lambda中,如何通过值捕获引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆