不使用std::function
是否可以获得lambda的捕获值?我问这个问题是因为我想将捕获的副本放到我自己的内存中,而std::function
无法做到这一点,因为它们不支持自定义分配器。
(我认为std::function
缺少分配器支持是有原因的,也许在lambda中捕获值背后的逻辑很难实现?但是如果可能的话,我想自己试试。)
背景:我要求学习更多关于C++中的lambda的知识。我想把捕获的值和引用指针放在我作为学术练习编写的线程池系统的过对齐内存中。我也非常喜欢用自动捕获来编写lambda的简洁性,我认为这会使编写界面变得非常容易。
class MyFunction {
public:
// I want more than just the function pointer,
// I also want the captured value copies or references too
// I'm unsure how to really accomplish this though.
MyFunction & operator=( ??? ) {
???
}
};
int main(){
int captureThis = 1;
MyFunction func = [=]()->void {
printf("%i", captureThis);
};
}
2条答案
按热度按时间pu82cl6c1#
检查lambda外部捕获的变量的值看起来不太好,但至少你可以使用一个工厂函数来产生它,它具有唯一的"lambda"模板类型(也可以在最终类型的auto的帮助下),这样你就可以在线程调用和初始化之间做额外的工作:
输出:
如果只是为了让线程数组处理lambda数组,可以使用智能指针和一个额外的容器结构体在工作分发期间装箱/取消装箱它们:
输出:
如果你在为容器进行自定义分配,你可以只为工厂函数使用第二个参数。下面的例子在堆栈缓冲区上使用placement-new。但是lambda本身仍然有一些其他的东西在它之外,使得容器的大小不会被它的lambda改变(就像函数指针一样):
输出:
jmp7cifd2#
考虑到您在评论中提到的线程池系统,您可以尝试多态方法:
现在,您可以将线程例程存储在
std::vector
中(注意:按值指向的指针将导致对象切片;很可能是std::unique_ptr
,根据用例,经典的原始指针也可能适合)。您甚至可以实现 both 变量,您的线程池管理器可以在线程创建函数中提供一个额外的参数,或者通过重载该函数(左值引用:创建引用 Package 器变量;r值参考:创建值变量,移动-构造它),例如:
关于对齐问题:特定的模板示例化将选择适合于模板参数类型的对齐方式,因此您不必考虑任何特殊情况。