In a lambda, does a by-value capture of a reference copy the underlying object?
C++C++11LambdaC++ Problem Overview
If a variable of reference type is captured in a lambda by value, is the referenced object copied or is it captured by reference?
Small sample with question:
#include <iostream>
struct Test {
int a;
};
void testFunc(const Test &test) {
auto a = [=] {
// is 'test' passed to closure object as a copy
// or as a reference?
return test.a;
} ();
std::cout << a;
}
int main() {
Test test{1};
testFunc(test);
}
C++ Solutions
Solution 1 - C++
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
- 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?