有没有办法在传递给标准算法的谓词中获取元素的偏移量?
Is there a way to get element's offset in predicates passed to std algorithms?
Algorithms library 中使用的 predicates/operators 接受相应迭代器的 value_type 的元素。我想编写一个使用元素在范围内的偏移量的谓词。
例如,考虑以下 code:
#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);
}
我的问题是:
- 是否有一种“不错”的方法(即比我上面介绍的方法更好)来找到元素在范围内的偏移量?
- 是否保证上述技术适用于任何数据类型(代替
int
)?因为 const &
可以绑定到一个 r 值,所以我担心我可能会得到一些临时副本的地址。
- 可以为关联(非连续)数据结构实现类似的东西吗?
- 如果我使用接受 std::ExecutionPolicy 的算法重载,任何答案都会改变吗?
编辑:
有关我的问题的更多信息:
考虑在 std::vector
之上创建的多维数据结构。在此数据结构中,索引是“托管的”,因此我可以同时对所有数据结构执行某些操作。此外,数据类型本身可以是索引。
因此,当我修改索引时,我需要知道“域”索引和“范围”索引之间是否存在某种关系。
至此,我用了一个循环。我想看看我是否可以通过使用标准的并行算法来提高性能。
编辑#2:
我最终实现了一个简单的基于顺序循环的算法,用于(罕见的)特定索引类型同时出现在域和范围中的情况。
对于其他情况,上述练习是不必要的,我使用 par_unseq
执行策略获得了大约 60% 的加速! (但出于某种原因,par
没有)。
Is the technique above guaranteed to work for any data type (in place of int)? Because const & can bind to an r-value I'm worried I might get the address of some temporary copy.
没有。这仅适用于 std::vector
或 std::array
或保证所有元素都存储在连续内存中的原始指针。对于他们来说,它适用于存储在那里的任何数据类型。但是,即使对于 std::deque
中的随机访问迭代器,这种技术也会导致 UB。
Can something similar be implemented for associative data structures?
我怀疑,因为这甚至不适用于随机访问迭代器,例如前向迭代器的情况会更糟,看起来你有 XY 问题并且需要指定你想要实现的目标。
- Is there a "nice" way (i.e. better than what I presented above) to find the element's offset in the range?
不,一般情况下不会。
- Is the technique above guaranteed to work for any data type
几乎(除非您显然必须更改参数的类型以对应于正在迭代的任何数据类型)。您必须使用 std::addressof
才能使其与重载 addressof 运算符的类型一起使用(但谁会这样做?)。
- Can something similar be implemented for associative data structures?
不太像。您所展示的内容有效,但仅适用于连续的迭代器,即数组的迭代器(一般意义上,包括向量和字符串)。
假设你正在使用一个按顺序迭代元素的算法(这就是执行策略确实重要的地方),那么一个通用的解决方案是使用累加器:
auto offset_value_mismatch = [](auto& x) {
static int i;
return i++ == x;
}
- Do any of the answers change if I use the algorithm overloads accepting an std::ExecutionPolicy?
地址减法和累加器都只适用于顺序算法,不适用于并行算法。从技术上讲,可以使用锁使累加器与并行策略(但不是无序的)一起工作,但据我所知这样做没有任何优势。
Algorithms library 中使用的 predicates/operators 接受相应迭代器的 value_type 的元素。我想编写一个使用元素在范围内的偏移量的谓词。
例如,考虑以下 code:
#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);
}
我的问题是:
- 是否有一种“不错”的方法(即比我上面介绍的方法更好)来找到元素在范围内的偏移量?
- 是否保证上述技术适用于任何数据类型(代替
int
)?因为const &
可以绑定到一个 r 值,所以我担心我可能会得到一些临时副本的地址。 - 可以为关联(非连续)数据结构实现类似的东西吗?
- 如果我使用接受 std::ExecutionPolicy 的算法重载,任何答案都会改变吗?
编辑:
有关我的问题的更多信息:
考虑在 std::vector
之上创建的多维数据结构。在此数据结构中,索引是“托管的”,因此我可以同时对所有数据结构执行某些操作。此外,数据类型本身可以是索引。
因此,当我修改索引时,我需要知道“域”索引和“范围”索引之间是否存在某种关系。
至此,我用了一个循环。我想看看我是否可以通过使用标准的并行算法来提高性能。
编辑#2:
我最终实现了一个简单的基于顺序循环的算法,用于(罕见的)特定索引类型同时出现在域和范围中的情况。
对于其他情况,上述练习是不必要的,我使用 par_unseq
执行策略获得了大约 60% 的加速! (但出于某种原因,par
没有)。
Is the technique above guaranteed to work for any data type (in place of int)? Because const & can bind to an r-value I'm worried I might get the address of some temporary copy.
没有。这仅适用于 std::vector
或 std::array
或保证所有元素都存储在连续内存中的原始指针。对于他们来说,它适用于存储在那里的任何数据类型。但是,即使对于 std::deque
中的随机访问迭代器,这种技术也会导致 UB。
Can something similar be implemented for associative data structures?
我怀疑,因为这甚至不适用于随机访问迭代器,例如前向迭代器的情况会更糟,看起来你有 XY 问题并且需要指定你想要实现的目标。
- Is there a "nice" way (i.e. better than what I presented above) to find the element's offset in the range?
不,一般情况下不会。
- Is the technique above guaranteed to work for any data type
几乎(除非您显然必须更改参数的类型以对应于正在迭代的任何数据类型)。您必须使用 std::addressof
才能使其与重载 addressof 运算符的类型一起使用(但谁会这样做?)。
- Can something similar be implemented for associative data structures?
不太像。您所展示的内容有效,但仅适用于连续的迭代器,即数组的迭代器(一般意义上,包括向量和字符串)。
假设你正在使用一个按顺序迭代元素的算法(这就是执行策略确实重要的地方),那么一个通用的解决方案是使用累加器:
auto offset_value_mismatch = [](auto& x) {
static int i;
return i++ == x;
}
- Do any of the answers change if I use the algorithm overloads accepting an std::ExecutionPolicy?
地址减法和累加器都只适用于顺序算法,不适用于并行算法。从技术上讲,可以使用锁使累加器与并行策略(但不是无序的)一起工作,但据我所知这样做没有任何优势。