带有unique_ptr捕获的asio lambda

α

我正在使用asio独立版1.10.6和vs2015 rc。

vs2015支持unique_ptr捕获。所以我写了一些代码如下:

auto data = std::make_unique<std::string>("abc");
auto buffer = asio::buffer(data->c_str(), data->size());
asio::async_write(s, buffer, [data = std::move(data)](
  const asio::error_code& error, size_t byte_transferred) mutable {
  do_something(std::move(data), error, byte_transferred);
});

但是当我编译代码时,编译器说:

错误C2280:..试图引用已删除的功能

据我了解,它表示我尝试复制lambda,并且由于lambda捕获了a std::unique_ptr,因此它是不可复制的

让我感到困惑的是,为什么Asio想要复制Lambda但不移动Lambda。

我的代码有什么问题?如何解决呢?

========================

完整的代码是:

void do_something(std::unique_ptr<std::string> data) { }

void compile_failed() {
  asio::io_service io_service;
  asio::ip::tcp::socket s(io_service);

  auto data = std::make_unique<std::string>("abc");
  auto buffer = asio::buffer(data->c_str(), data->size());

  asio::async_write(s, buffer, [data = std::move(data)](const asio::error_code& error,
    size_t byte_transferred) mutable {
    do_something(std::move(data));
  });
}

template<typename T > struct lambda_evil_wrap {
  mutable T ptr_;
  lambda_evil_wrap(T&& ptr) : ptr_(std::forward< T>(ptr)) {}
  lambda_evil_wrap(lambda_evil_wrap const& other) : ptr_(std::move(other.ptr_)) {}
  lambda_evil_wrap & operator=(lambda_evil_wrap& other) = delete;
};

void compile_success_but_very_danger() {
  asio::io_service io_service;
  asio::ip::tcp::socket s(io_service);

  auto data = std::make_unique<std::string>("abc");
  auto buffer = asio::buffer(data->c_str(), data->size());

  lambda_evil_wrap<std::unique_ptr<std::string>> wrapper(std::move(data));
  asio::async_write(s, buffer, [wrapper](const asio::error_code& error,
    size_t byte_transferred) mutable {
    do_something(std::move(wrapper.ptr_));
  });
}

int _tmain(int argc, _TCHAR* argv[])
{
    return 0;
}

作为代码,如果我将unique_ptr包装到一个可复制的对象,则编译就可以了。但是lambda_evil_wrap :: lambda_evil_wrap(lambda_evil_wrap const&a)确实很糟糕并且不安全。我不知道asio作者是否编写了一些代码如下所示:

Handler handler2(handler);
handler(...); // Crash here
坦纳·桑斯伯里(Tanner Sansbury)

原始代码中的错误是处理程序未能满足Handler类型要求,因为它不是CopyConstructible

处理程序必须满足CopyConstructible类型的要求(C ++ Std,20.1.3)。

正如Boost.Asio的C ++ 11对可移动处理程序的支持所指出的那样,在可能的情况下,Boost.Asio将首选move构造函数而不是copy构造函数,但该处理程序仍必须是可复制构造的:

[...] Boost.Asio的实现将优先使用处理程序的move构造函数,而不是其复制构造函数。在某些情况下,Boost.Asio可能能够消除对处理程序的副本构造函数的所有调用。但是,处理程序类型仍然需要可复制构造。

要解决此问题,可以考虑使用std::shared_ptr代替std::unique_ptr,从而使lambda具有可复制构造性。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

带有 lambda 删除器的 Unique_ptr

如何使用捕获的unique_ptr返回Lambda

带有lambda自定义删除程序的std :: unique_ptr无法编译

将带有unique_ptr的可变lambda传递给const&std :: function

在C ++ 14 Lambda表达式中捕获并移动unique_ptr

将在lambda捕获站点上构建的unique_ptr移到向量中失败

C++17 unique_ptr lambda 按值捕获是可以的,但不能按引用

如果使用lambda,std :: unique_ptr如何没有大小开销

When moving a unique_ptr into a lambda, why is it not possible to call reset?

如何将lambda用作std :: unique_ptr的Deleter?

传递lambda作为函数指针,该lambda返回多态的unique_ptr

带有 unique_ptr 的工厂模式

Lambda捕获

Boost.Asio lambda 捕获无法编译

带有 if 语句的 Lambda

是否可以将这个Lambda传递给`unique_ptr`终生可用?

为什么我不能在C ++ 14的lambda中移动std :: unique_ptr?

C ++ 11:使用自定义Lambda Deleter返回std :: unique_ptr

我们可以使用lambda创建unique_ptr吗?

为什么在移动Unique_ptr时在lambda中调用复制构造函数?

unique_ptr 的 lambda 删除器导致编译错误 vs 函子

如何使用lambda和功能作为unique_ptr的自定义删除器

将带有捕获的lambda传递给模板化函数

如何在带有捕获的函数中传递lambda?

将带有已移动捕获的lambda传递给函数

在 lambda 中捕获 shared_ptr

带有std :: unique_ptr的clang错误

调用带有unique_ptr对象的函数

返回带有抽象类的 unique_ptr