async 不会在 Visual Studio 2015 中调用移动构造函数
Posted
技术标签:
【中文标题】async 不会在 Visual Studio 2015 中调用移动构造函数【英文标题】:async doesn't invoke move constructor in Visual Studio 2015 【发布时间】:2015-10-06 08:53:49 【问题描述】:我在 Visual Studio 2015 社区编译包含以下内容的代码时遇到问题
auto f = async(launch::async,
&WorkerThread<Hash>::run,
WorkerThread<Hash>(mInputFile, mOutputFile),
i, numthreads, mBlockSize);
futures.push_back(std::move(f));
好吧,类似的问题已经在这里问了几十次了,但通常问题出在某处缺少std::move
。
模板类WorkerThread<Hash>
不可复制(已删除复制构造函数和复制赋值运算符),但可移动。上面的代码产生C2280: "WorkerThread<Hash>::WorkerThread(const WorkerThread<Hash> &)": attempted to reference deleted function
(这是我的翻译)。
似乎默认情况下它不会生成移动构造函数,在我的情况下这很好。当我将它们显式设置为default
时,我得到了同样的错误,但现在它指的是std::_Binder<std::_Unforced,_Ty,WorkerThread<Hash>,unsigned int,unsigned int,__int64>::_Binder(const std::_Binder<std::_Unforced,_Ty,WorkerThread<Hash>,unsigned int,unsigned int,__int64> &)
。
非常欢迎任何想法。
更新:MCVE
如果您有上述编译器可用,请尝试编译并报告结果。我认为这可能是我的安装问题。
#include<future>
#include<memory>
class Foo
public:
Foo() :mData(new int[100])
void run()
private:
std::unique_ptr<int[]> mData;
;
int main()
auto f = std::async(std::launch::async, &Foo::run, Foo());
f.get();
【问题讨论】:
您没有发布所有错误,但我猜您可能应该使用 futures.emplace_back(std::move(f));而不是 push_back? @Jonathan,不,同样的结果 @T.C.,完成。这段代码不适合我。 MSVC 错误。它将它打包成一个std::function
,这是不应该的。
在 MS Connect 上有几个与此相关的错误报告。我能找到的最新消息是:std::async (still?) does not accept move only types。支持它并将其标记为可重现不会有什么坏处。这很烦人,因为他们的 std::thread
实现似乎支持仅移动参数就好了(我猜你可以将其用作解决方法)。
【参考方案1】:
编辑:该错误已在 MSVC 2015 Update 2 中修复。
这是MSVC bug(帽子提示@bogdan 用于查找报告)。它的async
(和packaged_task
,似乎是)实现将仿函数存储到std::function
,它不支持仅移动类型——因此不能在符合要求的实现中使用。
一个简单的解决方法是改用shared_ptr
:
auto f = async(launch::async,
&WorkerThread<Hash>::run,
std::make_shared<WorkerThread<Hash>>(mInputFile, mOutputFile),
i, numthreads, mBlockSize);
futures.push_back(std::move(f));
也可以考虑 Lambda(沿着 [=]WorkerThread<Hash>(mInputFile, mOutputFile).run(i, numthreads, mBlockSize);
的行),但这会导致行为发生变化:WorkerThread<Hash>
不再在调用 async
的线程中构造,而是在线程 async
中构造产卵。
【讨论】:
看看你能不能找到 Herb Sutter 关于std::async
主题的视频。 IIRC,不是它的忠实粉丝 - 由于一些设计缺陷。以上是关于async 不会在 Visual Studio 2015 中调用移动构造函数的主要内容,如果未能解决你的问题,请参考以下文章
在 Visual Studio 中,与 std::async 一起使用时未调用“thread_local”变量的析构函数,这是一个错误吗?
异步/等待异常和 Visual Studio 2013 调试输出行为
Visual Studio 2012 项目不会在 2010 年打开
Visual Studio Online 上的远程分支不会出现在 Visual Studio 2015 Team Explorer 上