如何将 lambda 与临时对象一起使用来实现移动语义?

问题描述 投票:0回答:1

假设我有类“X”,它实现了移动语义。
在这个类中copy-ctor被删除:

class X
{
    /* ...data... */
    
    X(X&& other)
    { 
        /* ...move code... */
    }

    X& operator=(X&& other)
    {
        /* ...move code... */
        return *this;
    }

private:
    X(const X&) = delete;
    X& operator=(const X&) = delete;
};

...我有接收类 X 的函数“foo”:

void foo( X x)
{
    /* ...do something with x... */
}

...我有一个预定义的 lambda,它将 X 发送到 foo:

auto l = [](X x){ foo(std::move(x));};

...我有一些计时器方法可以接收 std 函数以供稍后执行:

SetTimer( int timeout, std::function<void()> doThis);

...在代码的更深处,使用 lambda,我想将 X 传递给我的计时器方法:

X x(...data...);
SetTimer( 1000, [=](){ l(x);});

我找不到一种方法来编译此代码而不出现各种编译错误。
请记住,在调用“foo()”之前,堆栈上的“x”将被破坏。
会很高兴获得指导。

c++ lambda std-function
1个回答
0
投票

好吧,首先,我不厌其烦地创建了一个mre(请不要让我再这样做):

#include <utility>
#include <functional>

class X
{
public:
    X () { }
    X (X&&) { }
    X& operator= (X&&) { return *this; }

private:
    X (const X&) = delete;
    X& operator= (const X&) = delete;
};

void foo (X) { }
auto l = [] (X x) { foo (std::move (x)); };
void SetTimer (int, std::function <void ()>) { }

int main ()
{
    X x;
    SetTimer (1000, [=] () { l (x);} );
}

现在我们可以看到捕获和调用

l
都试图复制
x
。但解决方案很简单:

  • 通过引用捕获
    x
  • 调用时移动它,而不是复制它
    l
int main ()
{
    X x;
    SetTimer (1000, [&] () { l (std::move (x));} );
}

现场演示

如果您可以使用它们,另请参阅上面@holyblackcat关于更现代解决方案的评论。他的建议

[x = std::move (x)] () mutable
似乎不起作用,不知道为什么。我非常怀疑有人会因为留下一个悬而未决的参考而否决这个答案。

© www.soinside.com 2019 - 2024. All rights reserved.