Подтвердить что ты не робот

В лямбда, как ссылка захватывается по значению

Если переменная ссылочного типа записывается в лямбда по значению, выполняется ли она по ссылке или значению?

Небольшая выборка с вопросом:

#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);
}
4b9b3361

Ответ 1

По значению. Компилируемый пример:

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

Я предполагаю, что этот параграф стандарта С++ применяется:

5.1.2 Лямбда-выражения

(...) 14. Объект захвачен copy, если он неявно записан, а capture-default is = или если он явно захвачен с захватом, который не включает &. Для каждого объекта, захваченного копией, неназванный нестатический член данных объявляется в типе замыкания. Порядок объявления этих членов не указан. Тип такого элемента данных является типом соответствующего захваченного объекта, если объект не является ссылку на объект, или ссылочный тип иначе. [ Примечание: если захваченный объект является ссылкой на функция, соответствующий элемент данных также является ссылкой на функцию. - end note]

Это действительно имеет смысл - если локальные переменные передаются по значению и параметру, переданному по ссылке "действует" как локальная переменная в функции, почему она должна быть передана ссылкой вместо значения?