问题描述
以下片段不能用 GCC 10 (Compiler Explorer link) 编译:
#include <vector>
#include <algorithm>
#include <execution>
struct T
{
int const ID; // Not Cpp17copyAssignable
};
int f(std::vector<T> const &v)
{
if (v.empty()) return -1;
return std::min_element(std::execution::par_unseq,v.begin(),v.end(),[](T const &lhs,T const &rhs) { return lhs.ID < rhs.ID; })->ID;
}
因为 T
不是 Cpp17copyAssignable
:
error: use of deleted function 'T& T::operator=(const T&)'
643 | __min_val = __obj.__min_val;
| ~~~~~~~~~~^~~~~~~~~~~~~~~~~
我在 cppreference 或 [algorithms] 中都找不到这样的要求。我错过了吗?
解决方法
C++ 标准不要求传递给并行算法的序列值是可赋值的(也不是可复制构造的,也不是可默认构造的),除非非并行对应物需要。不接受此类值的实现是不合格的。
[algorithms.parallel.defns]/2 并行算法通过调用以下函数访问通过其参数间接访问的对象:
...
(2.2) — 对其规范要求的那些序列元素的操作。
...
这表示算法不应该对值类型提出超过必要的要求。
有时允许并行算法复制元素:
[algorithms.parallel.exec]/2 除非另有说明,否则实现可以从 T
和 {{ 1}} 是真的。
但仅适用于那些可简单复制构造的元素,然后通过复制构造函数,而不是通过赋值。