Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ std::函数和std::打包的任务转换_C++_C++11_Clang - Fatal编程技术网

C++ std::函数和std::打包的任务转换

C++ std::函数和std::打包的任务转换,c++,c++11,clang,C++,C++11,Clang,我试图将std::packaged_任务移动到std::function的std::vector,因为std::packaged_任务具有void操作符()(ArgTypes…args)重载,它应该可以转换为std::function,是吗 这不能在MSVC和Clang上编译,MSVC抱怨无法将void转换为int,Clang抱怨为std::packaged_task删除了复制构造函数,不应该在这里调用std::vector::push_的版本?怎么回事,这是个虫子吗 int main ()

我试图将
std::packaged_任务
移动到
std::function
std::vector
,因为
std::packaged_任务
具有
void操作符()(ArgTypes…args)
重载,它应该可以转换为
std::function
,是吗

这不能在MSVC和Clang上编译,MSVC抱怨无法将void转换为int,Clang抱怨为
std::packaged_task
删除了复制构造函数,不应该在这里调用
std::vector::push_的版本?怎么回事,这是个虫子吗

int main () 
{
    std::vector<std::function<void()>> vec;
    std::packaged_task<int()> task( [] { return 100; } );
    vec.push_back( std::move(task) );
}
int main()
{
std::vec;
std::打包的_任务任务([]{return 100;});
向量推回(标准::移动(任务));
}
下面是关于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.
在main.cpp:1中包含的文件中:
在/usr/bin/./lib/c++/v1/iostream:38中包含的文件中:
在/usr/bin/./lib/c++/v1/ios:216中包含的文件中:
在/usr/bin/./lib/c++/v1/_语言环境15中包含的文件中:
在/usr/bin/./lib/c++/v1/string:434中包含的文件中:
在/usr/bin/./lib/c++/v1/算法中包含的文件中:594:
/usr/bin/。/lib/c++/v1/内存:2236:15:错误:调用的已删除构造函数
'std::_1::打包的_任务'
__第一个参数(_-VSTD::forward(get(u-first-args))…)
^        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/。/lib/c++/v1/memory:2414:15:注意:在函数的实例化中
模板特化
'std::uu 1::uu libcpp\u compressed\u pair\u imp::u libcpp\u compressed\u pair\u imp'
在此请求
:base(uu pc,_VSTD::move(u first_args),_VSTD::move(u second_args),
^
/usr/bin/。/lib/c++/v1/functional:996:11:注意:在函数的实例化中
模板特化
“std::uu 1::u compressed_pair::u compressed_pair”已在此处请求
:uu f_u(分段构造,_-VSTD::前向作为元组(u f),
^
/usr/bin/。/lib/c++/v1/functional:1035:17:注意:在成员的实例化中
函数'std::u 1::u函数::u func::u func'
在此请求
::新建(u p)u func(u f_u.first(),u f_u.second());
^
/usr/bin/。/lib/c++/v1/functional:1277:26:注意:在成员的实例化中
函数'std::uu 1::u函数::u函数::u克隆'
在此请求
::新建(u f_u)FF(_VSTD::move(u f));
^
/usr/bin/。/lib/c++/v1/memory:1681:31:注意:在函数的实例化中
此处请求的模板专门化“std::\uu 1::function::function”
::新建((void*)\u p)\u向上(\u VSTD::forward(\u args)…);
^
/usr/bin/。/lib/c++/v1/memory:1608:18:注意:在函数的实例化中
此处请求了模板专门化“std::\uu 1::分配器::构造”
{{构造({p,{VSTD::forward({args)…);}
^
/usr/bin/。/lib/c++/v1/memory:1492:14:注意:在函数的实例化中
模板特化
此处请求了“std::_1::分配器特征::_构造”
{{uuuu构造({uu有\u构造(),
^
/usr/bin/。/lib/c++/v1/vector:1519:25:注意:在函数的实例化中
模板特化
此处请求了“std::_1::分配器_traits::construct”
__alloc_traits::construct(this->alloc(),
^
main.cpp:19:6:注意:在函数模板专门化的实例化中
此处请求“std::_1::vector::emplace_back”
后置向量(标准::移动(任务));
^
/usr/bin/。/lib/c++/v1/future:1956:5:注意:函数已显式标记
此处删除
打包任务(const packaged_task&)=删除;
^
产生2个错误。
它应该可以转换为
std::function
,是吗

否。
函数
的相关构造函数要求其参数可复制,而
打包的_任务
不可复制,它仅可移动,因为其复制构造函数和复制赋值运算符被删除。这是
函数
的不幸要求,但对于
乐趣来说是必要的Action
是可复制的,因为使用类型擦除来提取包装的可调用对象的详细信息


直到过程的后期,C++0x草案才要求可复制,但它是由最终的C++11标准添加的,所以这是我的错,对不起;-)早期支持概念的草案需要
CopyConstructible
概念,但当概念从草案中删除时,这一概念就消失了。

我今天遇到了这个问题。在异步服务中实现同步调用时,显然要做的事情是尝试将打包的任务存储在处理程序函数中,以便当异步处理程序完成时,调用方的未来可以准备就绪

不幸的是,c++11(和14)不允许这样做。跟踪它花费了我将近一天的开发时间,这个过程让我找到了这个答案

我找到了一个解决方案——用std::packaged_任务的专业化来替代std::function

感谢yngum和Jonathan发布问题和答案

代码:

//通用模板表单
模板
结构通用调用;
//部分专业化,涵盖大多数案例
模板
结构通用调用{
模板
通用呼叫(可呼叫和可呼叫)
:_impl{std::make_shared(std::forward(callable))}
{}
R运算符()(Args&&…Args)常量{
return _impl->call(std::forward(args)…);
}
私人:
结构概念{
虚拟R调用(Args&&…Args)=0;
virtual~concept()=默认值;
};
模板
结构模型:概念{
模型(可调用&可调用)
:_可调用(标准::移动(可调用))
{}
R调用(Args&&…Args)覆盖{
返回_可调用(std::forward(args)…);
}
可调用的,可调用的;
};
std::共享的ptr实现;
};
//特殊路径
// general template form
template<class Callable>
struct universal_call;

// partial specialisation to cover most cases
template<class R, class...Args>
struct universal_call<R(Args...)> {
    template<class Callable>
    universal_call(Callable&& callable)
    : _impl { std::make_shared<model<Callable>>(std::forward<Callable>(callable)) }
    {}

    R operator()(Args&&...args) const {
        return _impl->call(std::forward<Args>(args)...);
    }
private:
    struct concept {
        virtual R call(Args&&...args) = 0;
        virtual ~concept() = default;
    };

    template<class Callable>
    struct model : concept {
        model(Callable&& callable)
        : _callable(std::move(callable))
        {}
        R call(Args&&...args) override {
            return _callable(std::forward<Args>(args)...);
        }
        Callable _callable;
    };

    std::shared_ptr<concept> _impl;
};

// pathalogical specialisation for std::packaged_task - 
// erases the return type from the signature
template<class R, class...Args>
struct universal_call<std::packaged_task<R(Args...)>>
: universal_call<void(Args...)>
{
    using universal_call<void(Args...)>::universal_call;
};

// (possibly) helpful function
template<class F>
universal_call<F> make_universal_call(F&& f)
{
    return universal_call<F>(std::forward<F>(f));
}
std::vector<std::function<void()>> vec;
using task_t = std::packaged_task<int()>;
task_t task([] { return 100; });
vec.emplace_back( [t = std::make_shared<task_t>(std::move(task))]() {
    (*t)();
});