【问题标题】:Returning a lambda function with a move-capture [duplicate]返回带有移动捕获的lambda函数[重复]
【发布时间】:2014-06-23 22:06:18
【问题描述】:

我有一个函数,它使用移动捕获(仅限 C++1y)构造一个 lambda 函数并返回它。

#include <iostream>
#include <functional>
#include <memory>

using namespace std;

function<int ()> makeLambda(unique_ptr<int> ptr) {
    return [ ptr( move(ptr) ) ] () {
        return *ptr;
    };
}

int main() {
    // Works
    {
        unique_ptr<int> ptr( new int(10) );
        auto function1 = [ ptr(move(ptr)) ] {
            return *ptr;
        };
    }

    // Does not work
    {
        unique_ptr<int> ptr( new int(10) );
        auto function2 = makeLambda( std::move(ptr) );
    }

    return 0;
}

然而,似乎在返回时,unique_ptr&lt;int&gt; 的复制构造函数被调用了。为什么会这样/我该如何解决?

粘贴链接: http://coliru.stacked-crooked.com/a/b21c358db10c3933

【问题讨论】:

  • 如果将auto function1 = ... 更改为function&lt;int()&gt; function1 = ... 会发生什么。我认为问题在于使用std::function,而不是使用返回类型。
  • 嗯,它有所作为。如果我进行更改,第一部分将不再有效。
  • 哦,对不起。我误解了你的评论。
  • 顺便说一句,你的代码很吵。在现代 C++ 中,我可能更愿意写成 like this

标签: c++ lambda c++14


【解决方案1】:

问题在于 std::function&lt;int ()&gt; 返回类型,它试图复制 lambda。这将失败,因为复制构造函数由于std::unique_ptr 的存在而被隐式删除。不再将 lambda 存储在 std::function 对象中,而是使用返回类型推导,现在 lambda 将被移动。

auto makeLambda(unique_ptr<int> ptr) {
    return [ ptr( move(ptr) ) ] () {
        return *ptr;
    };
}

Live demo

您还应该将makeLambda 的参数类型更改为unique_ptr&lt;int&gt;&amp;&amp;

【讨论】:

  • 谢谢。至于 &&,这里有一个通过值传递 unique_ptr 的很好的论据:stackoverflow.com/questions/8114276/…
  • @par 谢谢你的链接,我以前没见过。 Nicol 确实为按值传递提供了一个很好的论据。但是,对于被传递给无条件移动对象的函数的仅移动类型,我认为我仍然更喜欢右值引用参数。恕我直言,如果有人试图将左值传递给函数,则错误消息会更清楚一些。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-14
  • 1970-01-01
  • 2021-04-12
  • 2012-01-28
相关资源
最近更新 更多