c++ - 如何在 std::function 中捕获 unique_ptr

标签 c++ c++14

我需要将 unique_ptr 移动到 std::function 闭包。我正在使用 generalized lambda captures在 C++14 中。

auto ptr = make_unique<Foo>();

// Works.
auto lambda = [p = move(ptr)] { };

// This does not compile.
std::function<void()> func = [p = move(ptr)] { };

它试图将 lambda 捕获复制而不是移动到 std::function 中。相关错误是:

 copy constructor of '' is implicitly deleted because field '' has a deleted copy
      constructor
  std::function<void()> func = [p = move(ptr)] { };

例子here会让这看起来有效。

请注意 answer here只是重复 isocpp.org 上的示例。

我可以按如下方式移动到 shared_ptr:

shared_ptr<Foo> s = move(ptr);

但这会产生另一个问题,因为我需要从我的 lambda 中调用一个需要 unique_ptr 的函数,而且我无法将 shared_ptr 转换回unique_ptr.

是否可以在 std::function 中捕获 unique_ptr

最佳答案

std::function 对象都可以复制

std::function是类型删除对象,支持复制存储的对象。

当您存储 std::unique_ptr在 lambda 中,该 lambda 不支持被复制。

所以 std::function很正确地提示。它是一种可以复制的类型,当传入某些东西时,就会计算出如何复制它。 “我无法复制它”不是一个有效的答案;所有std::function s可以复制。

工业强度解决方案:

有两种常见的方法可以解决这个问题。首先,您存储 std::functionstd::shared_ptr 中的状态某种。二、你自己写或者找一个非抄袭的std::function并改用它。

更“现代”std::function替换库支持许多有用的东西:

  1. 函数 View ,不拥有它们包装的内容。
  2. 只移动函数对象,不支持复制。
  3. 多重重载函数对象,一次支持超过 1 个签名。
  4. 固定大小的缓冲区,如果没有足够的自动存储而不是堆分配,则无法编译。
  5. 简单可复制的函数对象

出于各种特殊目的,我个人需要以上每一种。

然后你会使用moveonly_function<void()>当您不需要复制可调用对象时,您的代码就会编译。

但是,这对于您现在的需求来说可能太重了。

一个快速的解决方案是:

template<class F>
auto make_shared_function( F&& f ) {
  return
   [pf = std::make_shared<std::decay_t<F>>(std::forward<F>(f))]
   (auto&&...args)->decltype(auto)
   {
     return (*pf)( decltype(args)(args)... );
   };
}

现在每当你遇到这个问题时:

// This does not compile.
std::function<void()> func = make_shared_function([p = move(ptr)] { });

并且可调用对象的状态现在存储在共享指针中。

关于c++ - 如何在 std::function 中捕获 unique_ptr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56940199/

相关文章:

c++ - 无法在 C++ 中将二进制文件读入 std::vector<std::byte>

c++ - 如何定义两个依赖类?

c++ - GCC 因可变参数模板和指向成员函数的指针而失败

c++ - 如何使用自然语法实现线程安全的容器?

c++ - 当期望很长时函数返回 double

c++ - Geany 更好的语法突出显示

c++ - cuda执行 block 可以在执行过程中被打断吗?

c++ - 如何从内存中删除动态添加的节点?

c++ - sfinae 远离破坏者

c++ - g++内部编译器错误段错误与递归constexpr