【发布时间】:2018-09-10 14:02:01
【问题描述】:
我有这门课:
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).
- 这可能是什么?
- 我在 lambda 中捕获了
[*this],所以我有一个对象的副本,我确信(是吗?)异步执行不会有问题。我应该改为按参考值捕获吗?
在for_each lambda 中,我通过引用捕获,因为 temp 在范围内,我不会遇到它被销毁的问题。
【问题讨论】:
-
"我已经在 lambda 中捕获了 [*this],所以我有一个对象的副本" 这正是问题所在。
std::unique_ptr的copy-constructor被删除,复制std::vector<std::unique_ptr>的行为需要std::unique_ptr的copy-constructor可用。 -
您的 unique_ptr 不是唯一的!把它改成 shared_ptr 就可以了
-
EMX_Counter(const std::vector<std::unique_ptr<WireBase>>& w) : WiresList(w) {}这已经不行了,因为您尝试将unique_ptr实例从参数复制到您的列表中。 -
如果你解决了编译问题,请注意你有一个数据竞争:多个线程在没有同步的情况下推送到
temp向量。 -
终身问题;
std::future<std::vector<double>> getEmxEfficiency()的返回值是否应该在EMX_Counter被销毁后仍然有效?