C++ 容器如何处理lambda表达式的参数

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() {

继几个月前我的上一个问题之后,我想问一下容器如何在内部处理lampda表达式

假设有以下代码:

#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.你能确保在调用存储函数之前对象没有被破坏吗?还有,你指的是哪个
这个
?如果你描述的问题能在你的。