有没有办法将谓词中的元素偏移量传递给 std 算法?

Is there a way to get element's offset in predicates passed to std algorithms?

本文关键字:std 算法 偏移量 元素 谓词 有没有      更新时间:2023-10-16

算法库中使用的谓词/运算符接受相应迭代器的value_type元素。我想编写一个谓词,该谓词使用范围中元素的偏移量。

例如,考虑以下代码:

#include <algorithm>
#include <vector>
int main() {
std::vector<int> v{0, 1, 2, 3, 4, 5, 6};
auto offset_value_mismatch = [&v](int const & x){
return (x != (&x-&v.front()));
};
return std::any_of(v.begin(), v.end(), offset_value_mismatch);
}

我的问题是:

  1. 是否存在";漂亮的";找到元素在该范围内的偏移的方法(即比我上面介绍的更好(
  2. 上述技术是否保证适用于任何数据类型(代替int(?因为const &可以绑定到r值,我担心我可能会得到一些临时副本的地址
  3. 对于关联(而非连续(数据结构,是否可以实现类似的功能
  4. 如果我使用接受std::ExecutionPolicy的算法重载,答案会改变吗

编辑:

有关我的问题的更多信息:考虑在std::vector之上创建的多维数据结构。在这个数据结构中,索引是"0";被管理";,以便我可以同时对所有数据结构执行一些操作。此外,数据类型本身可以是索引。

因此,当我修改索引时,我需要知道";域";索引和";范围";指数

在这一点上,我使用了一个循环。我想看看我是否可以通过使用标准的并行算法来提高性能。


编辑#2:

我最终实现了一个简单的基于顺序循环的算法,用于(罕见的(某个索引类型同时出现在域和范围中的情况。对于其他情况,上面的练习是不必要的,并且我使用par_unseq执行策略可以加快大约60%!(但由于某种原因,par没有(。

以上技术是否保证适用于任何数据类型(代替int(?因为const&可以绑定到r值。我担心我可能会得到一些临时副本的地址。

否。这只适用于std::vectorstd::array或保证所有元素存储在连续内存中的原始指针。对他们来说,它适用于存储在那里的任何数据类型。但是,即使对于来自std::deque的随机访问迭代器,这种技术也会导致UB。

关联数据结构是否可以实现类似的功能?

我怀疑,因为这甚至不适用于随机访问迭代器,例如,前向迭代器的情况会更糟,看起来你有XY问题,需要指定你想要实现的目标。

  1. 是否存在"漂亮的";找到元素在该范围内的偏移的方法(即比我上面介绍的更好(

没有,一般情况下没有。

  1. 以上技术是否保证适用于任何数据类型

Almost(除了您显然必须更改参数的类型以对应于正在迭代的任何数据类型(。您必须使用std::addressof才能处理重载addressof运算符的类型(但谁会这样做呢?(。

  1. 是否可以为关联数据结构实现类似的功能

不太像那样。您所展示的内容有效,但仅适用于连续迭代器,即数组的迭代器(一般意义上,包括向量和字符串(。

假设您使用的算法按顺序迭代元素(这就是执行策略非常重要的地方(,那么一般的解决方案是使用累加器:

auto offset_value_mismatch = [](auto& x) {
static int i;
return i++ == x;
}
  1. 如果我使用接受std::ExecutionPolicy的算法重载,答案会改变吗

地址减法和累加器只能使用顺序算法,而不能使用并行算法。从技术上讲,累加器可以使用锁与并行策略(但不是无序的(一起工作,但据我所知,这样做没有任何好处。