C++ 容器如何处理lambda表达式的参数
继几个月前我的上一个问题之后,我想问一下容器如何在内部处理lampda表达式 假设有以下代码:C++ 容器如何处理lambda表达式的参数,c++,lambda,containers,C++,Lambda,Containers,继几个月前我的上一个问题之后,我想问一下容器如何在内部处理lampda表达式 假设有以下代码: #include <iostream> #include <type_traits> #include <queue> #include <functional> std::queue<std::function<void()>> funcs; class A { public: A() {
#include <iostream>
#include <type_traits>
#include <queue>
#include <functional>
std::queue<std::function<void()>> funcs;
class A
{
public:
A()
{
std::cout << "A constructor" << std::endl;
}
void foo(int a)
{
}
};
class ThePool
{
public:
template <typename _Callable, typename Object, typename... _Args>
void QueueFunction(_Callable __f, Object& obj, _Args... __args)
{
funcs.push([__f, &obj, &__args...]() mutable
{
(obj.*__f)(__args...);
});
}
};
int main(int argc, char** argv)
{
ThePool t;
A a;
int x = 5;
t.QueueFunction(&A::foo, a, x);
std::function<void()> func = funcs.back();
func();
return 0;
}
#包括
#包括
#包括
#包括
std::队列函数;
甲级
{
公众:
()
{
std::cout容器确实可以自由复制其元素。此外,std::function
具有存储的functor是CopyConstructible
,它当然会使用它。因此,您必须选择:
- 如果按值传递对象,则实际上不必担心对象的生存时间。但是,对对象副本(或使用复制的参数)调用成员函数可能不是您想要的
- 如果通过(某种形式的)引用传递对象(例如,将它们包装在
std::ref
中),则永远不会创建对象和参数的副本,但它们可能在调用排队成员函数之前超出范围
当前,在原始代码中,您正在lambda中创建obj
的副本(obj
是obj&
,但这与lambda捕获无关-如果不是通过引用显式捕获,它会复制)。要在lambda中保留引用,请通过引用捕获obj
([&obj]
),而不是按值。或者,传递包装在std::ref
中的对象
至于参数,它们目前都是复制的(在QueueFunction
以及lambda捕获中)。如果您不打算这样做,请参见上文
如果存储引用,则开始时提到的所有复制操作将只复制引用(而不是对象)。强制阅读:在lambda表达式中,您正在创建对象的副本。因此队列函数中的“&”没有实际效果(这不是您的意图)你是对的。我修改了这个例子。我的问题是,如果我通过引用传递obj和_参数会发生什么。打印a的地址和这个的地址是不同的。你的第二点是正确的。我在脑海中看到了这一点,但当我将obj改为&obj inside push时,我希望a的地址和这个地址相等。但这不是true.地址不同。@GeorgeTsoumplekas.你能确保在调用存储函数之前对象没有被破坏吗?还有,你指的是哪个这个?如果你描述的问题能在你的。