【问题标题】:Is it possible to pass a lambda with captured non-copyable (moved) value?是否可以传递具有捕获的不可复制(移动)值的 lambda?
【发布时间】:2017-05-12 15:54:26
【问题描述】:

我正在尝试制作一个可调用的对象,它本质上在内部有一个绑定的unique_ptr。我读过How to capture a unique_ptr into a lambda expression?

但我无法进一步传递 lambda。下面的代码编译失败,表明正在复制unique_ptr。我不太明白为什么它会尝试复制unique_ptr

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

using namespace std;

void f(std::function<void(int)> unary) {
    unary(42);
    unary(1337);
}

struct A{
    void woof(int i) {cout<< "woof " << i << "\n";}
};

int main(){
    auto another_unique = make_unique<A>();
    auto bound_p = [ p = move(another_unique) ] (int i) {p->woof(i);};
    bound_p(5);
    f( bound_p ); // does not compute
}

我还尝试在对 f 的调用中定义 lambda inline,以便它成为一个临时对象,并且可以移动到 f 中。但是错误是一样的。

是否可以将此类对象绑定/包装到可调用对象中并传递它们?

我的用例取决于unique_ptr,但我怀疑任何带有已删除副本 c'tor 的对象都会出现同样的问题。如果我错了,请告诉我或将主题编辑为不那么笼统。

【问题讨论】:

    标签: c++ lambda c++14 unique-ptr


    【解决方案1】:

    您不能在std::function 中放置任何只移动类型。该类要求类型是可复制的。

    处理此问题的更好方法是使f 成为调用给定参数的模板,而不是使用类型擦除的std::functionfunction 应该用于您想要保留仿函数副本的情况,而不是当您只想调用它时。

    【讨论】:

    • unary 应该是一个回调,所以我需要一些可以存储然后调用的东西。 f 是调用存储的可调用对象的模拟。
    • @luk32:嗯,std::function 没有只能移动的版本。因此,您的选择是从您的 lambda 中删除仅移动类型。或者写你自己的等价于std::function
    • A view_function 比普通模板类型 BTW 具有更好的含义。很遗憾std::function 被用于此目的。
    • @Jarod42:这不能满足他的需求,因为他明确希望它声明回调的所有权,并存储 unique_ptr 和所有内容。
    • f 不必取得所有权,因此使用类似function_viewpassing_functions_to_functions 就足够了。
    猜你喜欢
    • 2020-03-17
    • 2018-05-26
    • 1970-01-01
    • 1970-01-01
    • 2018-06-08
    • 2019-05-06
    • 1970-01-01
    • 2021-05-08
    • 1970-01-01
    相关资源
    最近更新 更多