c++ - std::function 和 std::packaged_task 转换

标签 c++ c++11 clang

我正在尝试移动 std::packaged_task进入std::vectorstd::function<void()> ,因为 std::packaged_taskvoid operator()( ArgTypes... args )过载,它应该可以转换为 std::function<void()> , 是的?

这不会在 MSVC 和 Clang 上编译,MSVC 提示无法将 void 转换为 int,clang 提示删除了 std::packaged_task 的复制构造函数 | , 不应移动 std::vector::push_back 的版本被叫到这里?这是怎么回事,这是一个错误吗?

int main () 
{
    std::vector<std::function<void()>> vec;
    std::packaged_task<int()> task( [] { return 100; } );
    vec.push_back( std::move(task) );
}

这是 clang 的神秘模板错误消息

In file included from main.cpp:1:
In file included from /usr/bin/../lib/c++/v1/iostream:38:
In file included from /usr/bin/../lib/c++/v1/ios:216:
In file included from /usr/bin/../lib/c++/v1/__locale:15:
In file included from /usr/bin/../lib/c++/v1/string:434:
In file included from /usr/bin/../lib/c++/v1/algorithm:594:
/usr/bin/../lib/c++/v1/memory:2236:15: error: call to deleted constructor of
      'std::__1::packaged_task<int ()>'
              __first_(_VSTD::forward<_Args1>(get<_I1>(__first_args))...)
              ^        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/c++/v1/memory:2414:15: note: in instantiation of function
      template specialization
      'std::__1::__libcpp_compressed_pair_imp<std::__1::packaged_task<int ()>,
      std::__1::allocator<std::__1::packaged_task<int ()> >,
      2>::__libcpp_compressed_pair_imp<const std::__1::packaged_task<int ()> &,
      const std::__1::allocator<std::__1::packaged_task<int ()> > &, 0, 0>'
      requested here
            : base(__pc, _VSTD::move(__first_args), _VSTD::move(__second_args),
              ^
/usr/bin/../lib/c++/v1/functional:996:11: note: in instantiation of function
      template specialization
      'std::__1::__compressed_pair<std::__1::packaged_task<int ()>,
      std::__1::allocator<std::__1::packaged_task<int ()> >
      >::__compressed_pair<const std::__1::packaged_task<int ()> &, const
      std::__1::allocator<std::__1::packaged_task<int ()> > &>' requested here
        : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f),
          ^
/usr/bin/../lib/c++/v1/functional:1035:17: note: in instantiation of member
      function 'std::__1::__function::__func<std::__1::packaged_task<int ()>,
      std::__1::allocator<std::__1::packaged_task<int ()> >, void ()>::__func'
      requested here
    ::new (__p) __func(__f_.first(), __f_.second());
                ^
/usr/bin/../lib/c++/v1/functional:1277:26: note: in instantiation of member
      function 'std::__1::__function::__func<std::__1::packaged_task<int ()>,
      std::__1::allocator<std::__1::packaged_task<int ()> >, void ()>::__clone'
      requested here
            ::new (__f_) _FF(_VSTD::move(__f));
                         ^
/usr/bin/../lib/c++/v1/memory:1681:31: note: in instantiation of function
      template specialization 'std::__1::function<void
      ()>::function<std::__1::packaged_task<int ()> >' requested here
            ::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
                              ^
/usr/bin/../lib/c++/v1/memory:1608:18: note: in instantiation of function
      template specialization 'std::__1::allocator<std::__1::function<void ()>
      >::construct<std::__1::function<void ()>, std::__1::packaged_task<int ()>
      >' requested here
            {__a.construct(__p, _VSTD::forward<_Args>(__args)...);}
                 ^
/usr/bin/../lib/c++/v1/memory:1492:14: note: in instantiation of function
      template specialization
      'std::__1::allocator_traits<std::__1::allocator<std::__1::function<void
      ()> > >::__construct<std::__1::function<void ()>,
      std::__1::packaged_task<int ()> >' requested here
            {__construct(__has_construct<allocator_type, pointer, _Args...>(),
             ^
/usr/bin/../lib/c++/v1/vector:1519:25: note: in instantiation of function
      template specialization
      'std::__1::allocator_traits<std::__1::allocator<std::__1::function<void
      ()> > >::construct<std::__1::function<void ()>,
      std::__1::packaged_task<int ()> >' requested here
        __alloc_traits::construct(this->__alloc(),
                        ^
main.cpp:19:6: note: in instantiation of function template specialization
      'std::__1::vector<std::__1::function<void ()>,
      std::__1::allocator<std::__1::function<void ()> >
      >::emplace_back<std::__1::packaged_task<int ()> >' requested here
        vec.emplace_back( std::move(task) );
            ^
/usr/bin/../lib/c++/v1/future:1956:5: note: function has been explicitly marked
      deleted here
    packaged_task(const packaged_task&) = delete;
    ^
2 errors generated.

最佳答案

it should be convertable to std::function<void()>, yes?

没有。 function的相关构造函数要求它的参数是 CopyConstructible 和 packaged_task不是CopyConstructible,它只是MoveConstructible,因为它的复制构造函数和复制赋值运算符被删除了。这是 function 的不幸要求但对于 function 是必需的可复制,因为使用类型删除来抽象掉包装的可调用对象的细节。

直到过程的最后阶段,C++0x 草案才不需要 CopyConstructible,但它被 DR 1287 添加到最终的 C++11 标准中。所以这是我的错,抱歉 ;-) 早期启用概念的草稿需要CopyConstructible概念,但是当概念从草案中删除时,它就丢失了。

关于c++ - std::function 和 std::packaged_task 转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16889885/

相关文章:

c++ - 动态子对象内存分配 Clang++ vc g++

c++ - 使用 C++11 将数组设置为零

c++ - 内核不等待事件

c++ - 在 VS2013 中初始化 std::discrete_distribution

c++ - 非成员函数模板什么时候有内部链接?

c++ - libmediainfo 有替代方案吗?

c - C 中的初级函数

c - scan-build make 没有检测到任何错误

c++ - 拓扑排序不打印所有顶点

c++ - 多线程,线程间通信,同步