alf*_*lfC 7 algorithm foreach exception undo c++17
cppreference文档https://en.cppreference.com/w/cpp/algorithm/for_each 表示:
- 如果援引为算法的一部分功能的执行引发异常,并ExecutionPolicy是一个三个标准的政策,标准::终止被称为。对于任何其他ExecutionPolicy,该行为都是实现定义的。
我的解释是,这意味着我不能立即使用已for_each传递的函数并期望捕获异常或与之相关的某些信息。
我期望使用异常的原因是,我可以部分撤消(还原)for_each调用中所做的更改。(也许对此有更好的算法)。
但是,偶然地,我发现其历史版本for_each被记录为具有不同的,更有趣的行为:
- 如果策略为std :: parallel_vector_execution_policy,则调用std :: terminate
- 如果policy是std :: sequential_execution_policy或std :: parallel_execution_policy,则该算法将以包含所有未捕获异常的std :: exception_list退出。如果只有一个未捕获的异常,则算法可以将其重新抛出而无需包装在std :: exception_list中。在遇到第一个异常后返回之前,算法将执行多少工作尚未确定。
这似乎暗示terminate着有可能使用异常来代替ing。
那么,为什么std::exception_list要淘汰它呢?是否太有争议,太复杂,太昂贵(内存)?
即使我同意逻辑,但实际上我没有其他选择,因为并行for_each返回void(而不是UnaryFunction返回,这也很令人惊讶)。因此,std::exception_list在我看来,该协议是撤消未完成for_each指令的必要组成部分。
是否有理由期望一些新的自定义策略,例如par_with_failed_list将出现在允许undo输入的位置。
更多上下文:构造失败循环的这种失败模式用于容器。我想实现一个自定义(并行/顺序)uninitialized_value_construct_n,当(任何未排序的)构造失败时,该操作“撤消”(销毁)初始化的对象。
EDIT1:尽管如此,有可能在lambda中将捕获的变量传递给函数参数。此变量可以是共享的并发数据,可以在发生异常时存储异常(作为exception_list)。我想知道这是否已经完成。
EDIT2:我exception_list在HPX中找到了一个实现,
https : //github.com/STEllAR-GROUP/hpx/blob/master/hpx/exception_list.hpp
https://github.com/STEllAR-GROUP/hpx/blob/master /src/exception_list.cpp
std::exception_list给并行算法的规范和实现增加了很多复杂性,但没有太多相应的增益。
作为用户,您可以在函子中处理这种情况:
struct exception_info{
ElementType* element;
std::exception_ptr exception;
};
std::vector<exception_info> exceptions;
std::mutex exceptions_mutex;
std::vector<ElementType> range=...;
std::for_each(std::execution::par,range.begin(),range.end(),[&](ElementType& element){
try{ do_stuff(element); }
catch(...){
std::lock_guard guard(exceptions_mutex);
exceptions.push_back({&element,std::current_exception()});
}});
Run Code Online (Sandbox Code Playgroud)
该exceptions列表现在将包含指向引发异常的元素和引发的异常的指针列表。
| 归档时间: |
|
| 查看次数: |
160 次 |
| 最近记录: |