I'm doing some work that requires multiple frames to process and I want to know if the named copy-by-value syntax for lambdas will copy the data from a const ref, or if it will create a new refernce to that data. In my case the data is on the stack and I need the lambda to hold on to a copy of the data.
consider the very redacted code sample
#include<functional>
#include<iostream>
struct FData
{
int x = 5;
};
std::function<void()> test(const FData& in)
{
return [copy = in]()
{
std::cout << copy.x << std::endl;
};
}
int main()
{
std::function<void()> callback;
{//scoped to destroy obj1
FData obj1;
callback = test(obj1);
obj1.x = 3;
}
{
FData obj2;
obj2.x = 7; //attempt to overwrite obj1 memory
callback(); //use ?copy? of obj1 in the callback
}
return 0;
}
This outputs 5, so it seems to be correctly copying the data. But I have not been able to safely verify the type by means like typeid().name(). I'm not sure of a way to know this other than testing.
Capture by value works like any other assignment by value. In your example, the lambda's copy
member will be a copy of the FData
that in
refers to, copy
will not be a reference to that FData
. It doesn't matter that in
is itself a reference, because copy
is not a reference.
You can easily prove this without resorting to RTTI:
#include <functional>
#include <iostream>
struct FData
{
int id = 1;
int x = 5;
};
std::function<void()> test(const FData& in)
{
return [copy = in]()
{
std::cout << "addr=" << © << " id=" << copy.id << " x=" << copy.x << std::endl;
};
}
int main()
{
std::function<void()> callback;
{//scoped to destroy obj1
FData obj1;
std::cout << "addr=" << &obj1 << " id=" << obj1.id << " x=" << obj1.x << std::endl;
callback = test(obj1);
}
{
FData obj2;
obj2.id = 2;
obj2.x = 7; //attempt to overwrite obj1 memory
std::cout << "addr=" << &obj2 << " id=" << obj2.id << " x=" << obj2.x << std::endl;
callback();
}
return 0;
}
Output:
addr=0x7ffe23f86bb8 id=1 x=5
addr=0x7ffe23f86bb8 id=2 x=7
addr=0x7ffe23f86bc0 id=1 x=5