提问者:小点点

有没有一种方法可以在传递给std算法的谓词中获得元素的偏移量?


算法库中使用的谓词/运算符通过相应迭代器的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)? 因为常量&可以绑定到r值,我担心我可能会得到某个临时副本的地址。
  3. 是否可以为关联(非连续)数据结构实现类似的功能?
  4. 如果我使用接受std::executionpolicy的算法重载,是否会更改任何答案?

编辑:

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

因此,当我修改指数时,我需要知道“值”指数和“范围”指数之间是否存在某种关系。

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


共2个答案

匿名用户

  1. 有没有一种“好”的方法(即比我上面介绍的方法更好)来找到元素在范围内的偏移量?

不,一般不是。

几乎(除了您显然必须更改参数的类型以对应于正在迭代的任何数据类型)。 您必须使用std::addressof,才能使它与重载addressof运算符的类型一起工作(但是是谁做的呢?)。

不太像那样。 您所展示的方法是可行的,但仅适用于连续迭代器,即数组(一般意义上,包括向量和字符串)的迭代器。

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

auto offset_value_mismatch = [](auto& x) {
    static int i;
    return i++ == x;
}

地址减法和累加器都只使用顺序算法,而不使用并行算法。 从技术上讲,累加器可以使用锁来使用并行策略(但不是无序的),但据我所知,这样做并没有什么好处。

匿名用户

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

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

可以为关联数据结构实现类似的东西吗?

我怀疑这样做,因为这甚至不工作的随机存取迭代器,情况与前向迭代器,例如,将会更糟,看起来你有XY问题,需要指定什么你想要实现。