In a lambda, does a by-value capture of a reference copy the underlying object?

C++C++11Lambda

C++ 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

(...)

  1. 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?

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionYuryView Question on Stackoverflow
Solution 1 - C++SpookView Answer on Stackoverflow