C++20中std::future的类型要求?MSVC2019编译报错解析
std::future的类型要求与MSVC2019编译问题
cppreference未列出std::future的任何类型要求,但使用Visual Studio 2019编译以下代码时会报错,而GCC和Clang的libstdc++编译则可通过。
测试代码
#include <future> struct A { A(int&){} A(A&&) = default; A(A const&) = delete; A& operator=(A&&) = delete; A& operator=(A const&) = delete; }; int main(){ int v; std::async([&v]{ return A(v); }).get(); }
MSVC2019编译错误信息
example.cpp C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.29.30133\include\future(314): error C2280: 'A &A::operator =(A &&)': attempting to reference a deleted function <source>(9): note: see declaration of 'A::operator =' <source>(9): note: 'A &A::operator =(A &&)': function was explicitly deleted C:/data/msvc/14.29.30151/include\future(309): note: while compiling class template member function 'void std::_Associated_state<_Ty>::_Set_value_raw(_Ty &&,std::unique_lock<std::mutex> *,bool)' with [ _Ty=A ] C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.29.30133\include\future(305): note: see reference to function template instantiation 'void std::_Associated_state<_Ty>::_Set_value_raw(_Ty &&,std::unique_lock<std::mutex> *,bool)' being compiled with [ _Ty=A ] C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.29.30133\include\future(774): note: see reference to class template instantiation 'std::_Associated_state<_Ty>' being compiled with [ _Ty=A ] C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.29.30133\include\future(769): note: while compiling class template member function '_Ty &std::_State_manager<_Ty>::_Get_value(void) const' with [ _Ty=A ] C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.29.30133\include\future(884): note: see reference to function template instantiation '_Ty &std::_State_manager<_Ty>::_Get_value(void) const' being compiled with [ _Ty=A ] C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.29.30133\include\future(860): note: see reference to class template instantiation 'std::_State_manager<_Ty>' being compiled with [ _Ty=A ] <source>(17): note: see reference to class template instantiation 'std::future<A>' being compiled Compiler returned: 2
问题分析与解答
从错误信息来看,MSVC2019的标准库实现尝试调用A的移动赋值运算符,而该运算符已被显式删除。
根据C++标准,std::future存储的对象仅要求满足可移动构造(MoveConstructible),并不强制要求可移动赋值(MoveAssignable)。异步任务返回的对象应该直接在std::future的内部状态中通过移动构造完成初始化,而非先默认构造再执行赋值操作。
你的A类已经显式默认了移动构造函数,完全符合标准要求。GCC和Clang的libstdc++实现遵循了这一标准,因此可以正常编译。而MSVC2019的标准库实现中,_Associated_state::_Set_value_raw函数内部错误地使用了移动赋值来存储结果,这属于实现不符合标准的问题。
内容的提问来源于stack exchange,提问作者Benjamin Buch
相关产品推荐
相关产品推荐

