我有这门课:
class EMX_Counter {
private:
std::vector<std::unique_ptr<WireBase>> WiresList;
public:
EMX_Counter(const std::vector<std::unique_ptr<WireBase>>& w) : WiresList(w) {}
EMX_Counter(std::vector<std::unique_ptr<WireBase>>&& w) : WiresList(std::move(w)) {}
std::future<std::vector<double>> getEmxEfficiency();
};
WireBase
是一个抽象类(这里不重要,它是如何工作的)我需要一个独特的ptr,因为我需要多态性。也就是说,getEmxEfficiency()
需要一些时间,因为该向量包含至少28'000 / 30'000个项目,并且对该方法的单个调用很慢。
我决定使用并行方法来加速,这是结果:
std::future<std::vector<double>> EMX_Counter::getEmxEfficiency() {
return std::async([*this]() {
std::vector<double> temp;
std::for_each(std::execution::par, WiresList.begin(), WiresList.end(), [&](auto& PolyObject) {
double result = PolyObject->getPartialEfficiency();
//more time-expensive operations
temp.push_back( result );
});
return temp;
});
}
调用PolyObject->getPartialEfficiency();
返回一个double并且不抛出异常,它是“安全的”。
我正在使用最新的Visual Studio版本(昨天更新)和标志/std:c++17
。问题是我收到此错误:
std::unique_ptr<WireBase,std::default_delete<_Ty>>::unique_ptr(const
std::unique_ptr<_Ty,std::default_delete<_Ty>> &)': attempting to
reference a deleted function (file: xmemory0).
[*this]
,所以我有一个对象的副本,我确信(我是吗?)异步执行不会出现问题。我应该通过引用值来捕获吗?在for_each
lambda中,我通过引用捕获了因为temp在范围内而且我不会有被销毁的问题。
我应该使用此代码:
//global
auto mymutex = std::mutex{};
std::future<std::vector<double>> EMX_Counter::getEmxEfficiency() {
return std::async([=]() {
std::vector<double> temp;
std::for_each(std::execution::par, WiresList.begin(), WiresList.end(), [&](auto& PolyObject) {
//your code...
auto lock = std::lock_guard<std::mutex>{ mymutex };
temp.push_back( result );
});
return temp;
});
}
其中WiresList
被宣布为std::vector<std::shared_ptr<WireBase>>
。现在变量受到保护,我没有更多的编译时问题,因为有一个共享指针!