copy(...) 和 copy(seq, ...) 之间的关系
Posted
技术标签:
【中文标题】copy(...) 和 copy(seq, ...) 之间的关系【英文标题】:Relationship between copy(...) and copy(seq, ...) 【发布时间】:2019-08-15 18:07:58 【问题描述】:std::copy
有和没有执行策略参数之间是否存在正式关系?无论是在实践中还是在标准中。
例如,是不是这样简单,
namespace std
template<class It>
It copy(std::execution::sequenced_policy, It first, It last, It d_first)
return std::copy(first, last, d_first);
或
namespace std
template<class It>
It copy(std::execution::sequenced_policy, It first, It last, It d_first)
// using std::copy; // may not be needed
return copy(first, last, d_first);
请注意,在第一个版本中意味着我还需要重载copy(par::seq, ...)
。
还是这样
namespace std
template<class It>
It copy(std::execution::sequenced_policy, It first, It last, It d_first)
... not defined at all in terms of other `copy(It, ...)` or `std::copy(It, ...)`
原因是我想为一种特殊类型的迭代器重载复制算法(在自定义命名空间中)。
【问题讨论】:
【参考方案1】:[execpol.seq] 中提到的一个区别是
在执行并行算法的过程中,
execution::sequenced_policy
策略,如果调用一个元素 访问函数通过未捕获的异常退出,terminate()
应为 调用。
演示:
#include <execution>
#include <iostream>
#include <stdexcept>
struct C
C()
C& operator=(const C&)
throw std::runtime_error("copy failed");
;
int main()
C a[1];
C b[1];
try
std::copy(std::begin(a), std::end(a), std::begin(b));
catch(const std::runtime_error& ex)
std::cout << "Exception: " << ex.what() << "\n";
try
std::copy(std::execution::seq, std::begin(a), std::end(a), std::begin(b));
catch(const std::runtime_error& ex)
std::cout << "Exception: " << ex.what() << "\n";
可能的输出:
Exception: copy failed
terminate called after throwing an instance of 'std::runtime_error'
what(): copy failed
Aborted (core dumped)
【讨论】:
好的,这是一个非常有用的细节。这也降低了一个根据另一个实现的可能性,但它仍然是可能的(理想的?)。 @alfC 我认为标准允许使用std::execution::sequenced_policy
调用的函数使用没有 ExecutionPolicy 的函数版本,但如果抛出异常,则必须使用 terminate()
。尽管元素访问是按顺序完成的,但可能允许并行算法实现并行执行操作,但这只是代表我的猜测。
谢谢。这就说得通了。我的最终问题是我是否需要为自定义迭代器同时重载 copy 和 copy(seq。这还取决于 copy(seq 是否对 ADL 友好。可能它不是标准的,我只能靠我自己。
@alfC 哦,我已经制作了很多自定义迭代器,但我还没有为 copy
制作重载。当使用带有copy(par
的自定义迭代器时,我注意到它做了一些我没有准备好的奇怪的事情。如果我没记错的话,我测试过的par
实现在启动线程之前在范围内循环了一次,然后它实际上完成了工作。为未知范围创建迭代器很棘手,如果我没记错的话,it==end()
将取决于任何线程找到的结果...
不幸的是,必须重新发明井以实现具有错误处理和中断条件的并行算法。我认为必须有一种方法可以优雅地做到这一点,甚至可能没有分配。以上是关于copy(...) 和 copy(seq, ...) 之间的关系的主要内容,如果未能解决你的问题,请参考以下文章
std::copy、std::copy_backward 和重叠范围