C++ 如果给定一个像 [copy=val](){} 这样的命名捕获,lambda 浅拷贝 const Type& 会吗?
C++ Will a lambda shallow copy const Type& if it is given a named capture like [copy=val](){}?
我正在做一些需要处理多个帧的工作,我想知道 lambda 的命名按值复制语法是否会从常量引用复制数据,或者它是否会创建一个新的引用到那个数据。在我的例子中,数据在堆栈上,我需要 lambda 来保存数据的副本。
考虑经过严格编辑的代码示例
#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;
}
这输出了 5,所以它似乎正确地复制了数据。但是我无法通过 typeid().name() 之类的方式安全地验证类型。除了测试之外,我不确定有什么方法可以了解这一点。
Capture by value 与任何其他分配 by value 一样工作。在您的示例中,lambda 的 copy
成员将是 in
所指的 FData
的 copy,copy
不会引用 FData
。 in
本身是引用并不重要,因为 copy
不是引用。
您无需借助 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;
}
输出:
addr=0x7ffe23f86bb8 id=1 x=5
addr=0x7ffe23f86bb8 id=2 x=7
addr=0x7ffe23f86bc0 id=1 x=5
我正在做一些需要处理多个帧的工作,我想知道 lambda 的命名按值复制语法是否会从常量引用复制数据,或者它是否会创建一个新的引用到那个数据。在我的例子中,数据在堆栈上,我需要 lambda 来保存数据的副本。
考虑经过严格编辑的代码示例
#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;
}
这输出了 5,所以它似乎正确地复制了数据。但是我无法通过 typeid().name() 之类的方式安全地验证类型。除了测试之外,我不确定有什么方法可以了解这一点。
Capture by value 与任何其他分配 by value 一样工作。在您的示例中,lambda 的 copy
成员将是 in
所指的 FData
的 copy,copy
不会引用 FData
。 in
本身是引用并不重要,因为 copy
不是引用。
您无需借助 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;
}
输出:
addr=0x7ffe23f86bb8 id=1 x=5
addr=0x7ffe23f86bb8 id=2 x=7
addr=0x7ffe23f86bc0 id=1 x=5