对std::future执行then会导致编译错误

Implementation of then for std::future results in compilation error

本文关键字:编译 错误 then std future 执行      更新时间:2023-10-16

当我试图编译这个实现Visual Studio 2013 Update 3时,编译器说我引用了std::future 的已删除副本构造函数

#include <iostream>
#include <stdexcept>
#include <utility>
#include <chrono>
#include <future>
#include <thread>
template <typename T, typename Func>
auto then(std::future<T> future, Func func) -> std::future<decltype(func(future))>
{
    return std::async([] (std::future<T> future, Func func) {
        future.wait();
        func(std::move(future));
    }, std::move(future), std::move(func));
}

int main()
{
    then(std::async([] {
        std::this_thread::sleep_for(std::chrono::seconds(4));
        return 5;
    }), [] (std::future<int> f) {
        std::cout << f.get();
    }).get();
}

这是来自编译器的消息

1>------ Build started: Project: temp, Configuration: Debug Win32 ------
1>  temp.cpp
1>c:program files (x86)microsoft visual studio 12.0vcincludexrefwrap(58): error C2280: 'std::future<std::_Result_of<_Fty,>::type>::future(const std::future<std::_Result_of<_Fty,>::type> &)' : attempting to reference a deleted function
1>          with
1>          [
1>              _Fty=main::<lambda_671f15aca9913797c9b157283a9bc860>
1>          ]
1>          c:program files (x86)microsoft visual studio 12.0vcincludefuture(1140) : see declaration of 'std::future<std::_Result_of<_Fty,>::type>::future'
1>          with
1>          [
1>              _Fty=main::<lambda_671f15aca9913797c9b157283a9bc860>
1>          ]
1>          c:program files (x86)microsoft visual studio 12.0vcincludexrefwrap(118) : see reference to class template instantiation 'std::_Result_of<_Fty,std::future<std::_Result_of<main::<lambda_671f15aca9913797c9b157283a9bc860>,>::type> ,main::<lambda_94e6e075e2832fb9a811ae5846fdb72f> &>' being compiled
1>          with
1>          [
1>              _Fty=then::<lambda_fce0ad2065944df99f1af1e657f83fe2>
1>          ]
1>          c:program files (x86)microsoft visual studio 12.0vcincludefunctional(975) : see reference to class template instantiation 'std::result_of<_Funx (std::future<std::_Result_of<_Fty,>::type> ,main::<lambda_94e6e075e2832fb9a811ae5846fdb72f> &)>' being compiled
1>          with
1>          [
1>              _Funx=then::<lambda_fce0ad2065944df99f1af1e657f83fe2>
1>  ,            _Fty=main::<lambda_671f15aca9913797c9b157283a9bc860>
1>          ]
1>          c:program files (x86)microsoft visual studio 12.0vcincludexrefwrap(283) : see reference to class template instantiation 'std::_Do_call_ret<false,_Ret,then::<lambda_fce0ad2065944df99f1af1e657f83fe2>,std::tuple<std::future<std::_Result_of<_Fty,>::type>,main::<lambda_94e6e075e2832fb9a811ae5846fdb72f>>,std::tuple<>,std::_Arg_idx<0,1>>' being compiled
1>          with
1>          [
1>              _Ret=void
1>  ,            _Fty=main::<lambda_671f15aca9913797c9b157283a9bc860>
1>          ]
1>          c:program files (x86)microsoft visual studio 12.0vcincludefunctional(228) : see reference to function template instantiation '_Ret std::_Callable_obj<std::_Bind<false,_Ret,_Ty,std::future<std::_Result_of<_Fty,>::type>,main::<lambda_94e6e075e2832fb9a811ae5846fdb72f>>,false>::_ApplyX<_Rx,>(void)' being compiled
1>          with
1>          [
1>              _Ret=void
1>  ,            _Ty=then::<lambda_fce0ad2065944df99f1af1e657f83fe2>
1>  ,            _Fty=main::<lambda_671f15aca9913797c9b157283a9bc860>
1>  ,            _Rx=void
1>          ]
1>          c:program files (x86)microsoft visual studio 12.0vcincludefunctional(228) : see reference to function template instantiation '_Ret std::_Callable_obj<std::_Bind<false,_Ret,_Ty,std::future<std::_Result_of<_Fty,>::type>,main::<lambda_94e6e075e2832fb9a811ae5846fdb72f>>,false>::_ApplyX<_Rx,>(void)' being compiled
1>          with
1>          [
1>              _Ret=void
1>  ,            _Ty=then::<lambda_fce0ad2065944df99f1af1e657f83fe2>
1>  ,            _Fty=main::<lambda_671f15aca9913797c9b157283a9bc860>
1>  ,            _Rx=void
1>          ]
1>          c:program files (x86)microsoft visual studio 12.0vcincludefunctional(226) : while compiling class template member function 'void std::_Func_impl<_MyWrapper,_Alloc,_Ret,>::_Do_call(void)'
1>          with
1>          [
1>              _Alloc=std::allocator<std::_Func_class<void,>>
1>  ,            _Ret=void
1>          ]
1>          c:program files (x86)microsoft visual studio 12.0vcincludefunctional(495) : see reference to class template instantiation 'std::_Func_impl<_MyWrapper,_Alloc,_Ret,>' being compiled
1>          with
1>          [
1>              _Alloc=std::allocator<std::_Func_class<void,>>
1>  ,            _Ret=void
1>          ]
1>          c:program files (x86)microsoft visual studio 12.0vcincludefunctional(396) : see reference to function template instantiation 'void std::_Func_class<_Ret,>::_Do_alloc<_Myimpl,_Ty,_Alloc>(_Fty &&,_Alloc)' being compiled
1>          with
1>          [
1>              _Ret=void
1>  ,            _Ty=std::_Bind<false,void,then::<lambda_fce0ad2065944df99f1af1e657f83fe2>,std::future<std::_Result_of<main::<lambda_671f15aca9913797c9b157283a9bc860>,>::type>,main::<lambda_94e6e075e2832fb9a811ae5846fdb72f>>
1>  ,            _Alloc=std::allocator<std::_Func_class<void,>>
1>  ,            _Fty=std::_Bind<false,void,then::<lambda_fce0ad2065944df99f1af1e657f83fe2>,std::future<std::_Result_of<main::<lambda_671f15aca9913797c9b157283a9bc860>,>::type>,main::<lambda_94e6e075e2832fb9a811ae5846fdb72f>>
1>          ]
1>          c:program files (x86)microsoft visual studio 12.0vcincludefunctional(396) : see reference to function template instantiation 'void std::_Func_class<_Ret,>::_Do_alloc<_Myimpl,_Ty,_Alloc>(_Fty &&,_Alloc)' being compiled
1>          with
1>          [
1>              _Ret=void
1>  ,            _Ty=std::_Bind<false,void,then::<lambda_fce0ad2065944df99f1af1e657f83fe2>,std::future<std::_Result_of<main::<lambda_671f15aca9913797c9b157283a9bc860>,>::type>,main::<lambda_94e6e075e2832fb9a811ae5846fdb72f>>
1>  ,            _Alloc=std::allocator<std::_Func_class<void,>>
1>  ,            _Fty=std::_Bind<false,void,then::<lambda_fce0ad2065944df99f1af1e657f83fe2>,std::future<std::_Result_of<main::<lambda_671f15aca9913797c9b157283a9bc860>,>::type>,main::<lambda_94e6e075e2832fb9a811ae5846fdb72f>>
1>          ]
1>          c:program files (x86)microsoft visual studio 12.0vcincludefunctional(385) : see reference to function template instantiation 'void std::_Func_class<_Ret,>::_Reset_alloc<_Ty,std::allocator<std::_Func_class<_Ret,>>>(_Fty &&,_Alloc)' being compiled
1>          with
1>          [
1>              _Ret=void
1>  ,            _Ty=std::_Bind<false,void,then::<lambda_fce0ad2065944df99f1af1e657f83fe2>,std::future<std::_Result_of<main::<lambda_671f15aca9913797c9b157283a9bc860>,>::type>,main::<lambda_94e6e075e2832fb9a811ae5846fdb72f>>
1>  ,            _Fty=std::_Bind<false,void,then::<lambda_fce0ad2065944df99f1af1e657f83fe2>,std::future<std::_Result_of<main::<lambda_671f15aca9913797c9b157283a9bc860>,>::type>,main::<lambda_94e6e075e2832fb9a811ae5846fdb72f>>
1>  ,            _Alloc=std::allocator<std::_Func_class<void,>>
1>          ]
1>          c:program files (x86)microsoft visual studio 12.0vcincludefunctional(385) : see reference to function template instantiation 'void std::_Func_class<_Ret,>::_Reset_alloc<_Ty,std::allocator<std::_Func_class<_Ret,>>>(_Fty &&,_Alloc)' being compiled
1>          with
1>          [
1>              _Ret=void
1>  ,            _Ty=std::_Bind<false,void,then::<lambda_fce0ad2065944df99f1af1e657f83fe2>,std::future<std::_Result_of<main::<lambda_671f15aca9913797c9b157283a9bc860>,>::type>,main::<lambda_94e6e075e2832fb9a811ae5846fdb72f>>
1>  ,            _Fty=std::_Bind<false,void,then::<lambda_fce0ad2065944df99f1af1e657f83fe2>,std::future<std::_Result_of<main::<lambda_671f15aca9913797c9b157283a9bc860>,>::type>,main::<lambda_94e6e075e2832fb9a811ae5846fdb72f>>
1>  ,            _Alloc=std::allocator<std::_Func_class<void,>>
1>          ]
1>          c:program files (x86)microsoft visual studio 12.0vcincludefunctional(671) : see reference to function template instantiation 'void std::_Func_class<_Ret,>::_Reset<_Ty>(_Fty &&)' being compiled
1>          with
1>          [
1>              _Ret=void
1>  ,            _Ty=std::_Bind<false,void,then::<lambda_fce0ad2065944df99f1af1e657f83fe2>,std::future<std::_Result_of<main::<lambda_671f15aca9913797c9b157283a9bc860>,>::type>,main::<lambda_94e6e075e2832fb9a811ae5846fdb72f>>
1>  ,            _Fty=std::_Bind<false,void,then::<lambda_fce0ad2065944df99f1af1e657f83fe2>,std::future<std::_Result_of<main::<lambda_671f15aca9913797c9b157283a9bc860>,>::type>,main::<lambda_94e6e075e2832fb9a811ae5846fdb72f>>
1>          ]
1>          c:program files (x86)microsoft visual studio 12.0vcincludefunctional(671) : see reference to function template instantiation 'void std::_Func_class<_Ret,>::_Reset<_Ty>(_Fty &&)' being compiled
1>          with
1>          [
1>              _Ret=void
1>  ,            _Ty=std::_Bind<false,void,then::<lambda_fce0ad2065944df99f1af1e657f83fe2>,std::future<std::_Result_of<main::<lambda_671f15aca9913797c9b157283a9bc860>,>::type>,main::<lambda_94e6e075e2832fb9a811ae5846fdb72f>>
1>  ,            _Fty=std::_Bind<false,void,then::<lambda_fce0ad2065944df99f1af1e657f83fe2>,std::future<std::_Result_of<main::<lambda_671f15aca9913797c9b157283a9bc860>,>::type>,main::<lambda_94e6e075e2832fb9a811ae5846fdb72f>>
1>          ]
1>          c:program files (x86)microsoft visual studio 12.0vcincludefuture(735) : see reference to function template instantiation 'std::function<void (void)>::function<_Ty>(_Fx &&)' being compiled
1>          with
1>          [
1>              _Ty=std::_Bind<false,void,then::<lambda_fce0ad2065944df99f1af1e657f83fe2>,std::future<std::_Result_of<main::<lambda_671f15aca9913797c9b157283a9bc860>,>::type>,main::<lambda_94e6e075e2832fb9a811ae5846fdb72f>>
1>  ,            _Fx=std::_Bind<false,void,then::<lambda_fce0ad2065944df99f1af1e657f83fe2>,std::future<std::_Result_of<main::<lambda_671f15aca9913797c9b157283a9bc860>,>::type>,main::<lambda_94e6e075e2832fb9a811ae5846fdb72f>>
1>          ]
1>          c:program files (x86)microsoft visual studio 12.0vcincludefuture(735) : see reference to function template instantiation 'std::function<void (void)>::function<_Ty>(_Fx &&)' being compiled
1>          with
1>          [
1>              _Ty=std::_Bind<false,void,then::<lambda_fce0ad2065944df99f1af1e657f83fe2>,std::future<std::_Result_of<main::<lambda_671f15aca9913797c9b157283a9bc860>,>::type>,main::<lambda_94e6e075e2832fb9a811ae5846fdb72f>>
1>  ,            _Fx=std::_Bind<false,void,then::<lambda_fce0ad2065944df99f1af1e657f83fe2>,std::future<std::_Result_of<main::<lambda_671f15aca9913797c9b157283a9bc860>,>::type>,main::<lambda_94e6e075e2832fb9a811ae5846fdb72f>>
1>          ]
1>          c:program files (x86)microsoft visual studio 12.0vcincludefuture(893) : see reference to function template instantiation 'std::_Packaged_state<_Rx (void)>::_Packaged_state<_Ty>(_Fty2 &&)' being compiled
1>          with
1>          [
1>              _Rx=_Ret
1>  ,            _Ty=std::_Bind<false,void,then::<lambda_fce0ad2065944df99f1af1e657f83fe2>,std::future<std::_Result_of<main::<lambda_671f15aca9913797c9b157283a9bc860>,>::type>,main::<lambda_94e6e075e2832fb9a811ae5846fdb72f>>
1>  ,            _Fty2=std::_Bind<false,void,then::<lambda_fce0ad2065944df99f1af1e657f83fe2>,std::future<std::_Result_of<main::<lambda_671f15aca9913797c9b157283a9bc860>,>::type>,main::<lambda_94e6e075e2832fb9a811ae5846fdb72f>>
1>          ]
1>          c:program files (x86)microsoft visual studio 12.0vcincludefuture(893) : see reference to function template instantiation 'std::_Packaged_state<_Rx (void)>::_Packaged_state<_Ty>(_Fty2 &&)' being compiled
1>          with
1>          [
1>              _Rx=_Ret
1>  ,            _Ty=std::_Bind<false,void,then::<lambda_fce0ad2065944df99f1af1e657f83fe2>,std::future<std::_Result_of<main::<lambda_671f15aca9913797c9b157283a9bc860>,>::type>,main::<lambda_94e6e075e2832fb9a811ae5846fdb72f>>
1>  ,            _Fty2=std::_Bind<false,void,then::<lambda_fce0ad2065944df99f1af1e657f83fe2>,std::future<std::_Result_of<main::<lambda_671f15aca9913797c9b157283a9bc860>,>::type>,main::<lambda_94e6e075e2832fb9a811ae5846fdb72f>>
1>          ]
1>          c:program files (x86)microsoft visual studio 12.0vcincludefuture(1859) : see reference to function template instantiation 'std::_Task_async_state<_Ret,false>::_Task_async_state<_Ty>(_Fty2 &&)' being compiled
1>          with
1>          [
1>              _Ret=_Ret
1>  ,            _Ty=std::_Bind<false,void,then::<lambda_fce0ad2065944df99f1af1e657f83fe2>,std::future<std::_Result_of<main::<lambda_671f15aca9913797c9b157283a9bc860>,>::type>,main::<lambda_94e6e075e2832fb9a811ae5846fdb72f>>
1>  ,            _Fty2=std::_Bind<false,void,then::<lambda_fce0ad2065944df99f1af1e657f83fe2>,std::future<std::_Result_of<main::<lambda_671f15aca9913797c9b157283a9bc860>,>::type>,main::<lambda_94e6e075e2832fb9a811ae5846fdb72f>>
1>          ]
1>          c:program files (x86)microsoft visual studio 12.0vcincludefuture(1859) : see reference to function template instantiation 'std::_Task_async_state<_Ret,false>::_Task_async_state<_Ty>(_Fty2 &&)' being compiled
1>          with
1>          [
1>              _Ret=_Ret
1>  ,            _Ty=std::_Bind<false,void,then::<lambda_fce0ad2065944df99f1af1e657f83fe2>,std::future<std::_Result_of<main::<lambda_671f15aca9913797c9b157283a9bc860>,>::type>,main::<lambda_94e6e075e2832fb9a811ae5846fdb72f>>
1>  ,            _Fty2=std::_Bind<false,void,then::<lambda_fce0ad2065944df99f1af1e657f83fe2>,std::future<std::_Result_of<main::<lambda_671f15aca9913797c9b157283a9bc860>,>::type>,main::<lambda_94e6e075e2832fb9a811ae5846fdb72f>>
1>          ]
1>          c:program files (x86)microsoft visual studio 12.0vcincludefuture(1880) : see reference to function template instantiation 'std::_Associated_state<int> *std::_Get_associated_state<_Ret,std::_Bind<false,void,_Ty,std::future<std::_Result_of<_Fty,>::type>,main::<lambda_94e6e075e2832fb9a811ae5846fdb72f>>>(std::_Launch_type,std::_Bind<false,void,_Ty,std::future<std::_Result_of<_Fty,>::type>,main::<lambda_94e6e075e2832fb9a811ae5846fdb72f>> &&)' being compiled
1>          with
1>          [
1>              _Ty=then::<lambda_fce0ad2065944df99f1af1e657f83fe2>
1>  ,            _Fty=main::<lambda_671f15aca9913797c9b157283a9bc860>
1>          ]
1>          c:program files (x86)microsoft visual studio 12.0vcincludefuture(1897) : see reference to function template instantiation 'std::future<void> std::_Async<then::<lambda_fce0ad2065944df99f1af1e657f83fe2>,std::future<std::_Result_of<_Fty,>::type>,main::<lambda_94e6e075e2832fb9a811ae5846fdb72f>>(std::_Launch_type,then::<lambda_fce0ad2065944df99f1af1e657f83fe2> &&,std::future<std::_Result_of<_Fty,>::type> &&,main::<lambda_94e6e075e2832fb9a811ae5846fdb72f> &&)' being compiled
1>          with
1>          [
1>              _Fty=main::<lambda_671f15aca9913797c9b157283a9bc860>
1>          ]
1>          d:...temp.cpp(12) : see reference to function template instantiation 'std::future<void> std::async<then::<lambda_fce0ad2065944df99f1af1e657f83fe2>,std::future<std::_Result_of<_Fty,>::type>,main::<lambda_94e6e075e2832fb9a811ae5846fdb72f>>(then::<lambda_fce0ad2065944df99f1af1e657f83fe2> &&,std::future<std::_Result_of<_Fty,>::type> &&,main::<lambda_94e6e075e2832fb9a811ae5846fdb72f> &&)' being compiled
1>          with
1>          [
1>              _Fty=main::<lambda_671f15aca9913797c9b157283a9bc860>
1>          ]
1>          d:...temp.cpp(26) : see reference to function template instantiation 'std::future<void> then<std::_Result_of<_Fty,>::type,main::<lambda_94e6e075e2832fb9a811ae5846fdb72f>>(std::future<std::_Result_of<_Fty,>::type>,Func)' being compiled
1>          with
1>          [
1>              _Fty=main::<lambda_671f15aca9913797c9b157283a9bc860>
1>  ,            Func=main::<lambda_94e6e075e2832fb9a811ae5846fdb72f>
1>          ]
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

您依赖于在此处复制future<T>

template <typename T, typename Func>
auto then(std::future<T> future, Func func) 
-> std::future<decltype(func(future))>

你想做的事:

template <typename T, typename Func>
auto then(std::future<T> future, Func func) 
-> std::future<decltype(func(std::move(future)))>