The following code, compiled in VS2015, calls the Foo copy constructor when foo captured:
void bar(Foo& foo) { auto f = [foo]() { }; } Previously, mistakenly believed that inside lambda, foo should have remained a reference, by analogy with the usual functions:
template<typename T> void f(T foo) { // здесь доступен исходный объект foo, который был создан при вызове baz(Foo()); // в случае, если это была бы лямбда с захватом foo по значению, здесь получается копия } void bar(const Foo& foo) { f<const Foo&>(foo); } baz(Foo()); I didn’t understand the specification, did I understand correctly that when capturing by value, a constant variable would be created (using the copy constructor), available inside the lambda, of type Foo , regardless of whether the external variable is a reference to Foo or an instance of Foo .
update
What is interesting, if you call not f<const Foo&>(foo); but just f(foo) (second code example), then the template is instantiated with the type Foo , not Foo& . Those. With automatic type selection, the compiler does not distinguish between a reference or an instance.