简体   繁体   English

迭代 Boost multi_array 视图

[英]Iterating over a Boost multi_array view

Is there a way to iterate over all the elements of a view into a Boost multi_array ?有没有办法将视图的所有元素迭代到 Boost multi_array中? It's clear how to iterate over a Boost multi_array ;很清楚如何迭代 Boost multi_array namely, go over the range [array.data(), array.data() + array.num_elements()) .即,越过范围[array.data(), array.data() + array.num_elements()) But if I create a view into this array (that cuts out some subset of the array), obviously a continuous access using pointers would be impossible: the view would not correspond to any continuous block of memory.但是如果我在这个数组中创建一个视图(删除数组的某个子集),显然使用指针进行连续访问是不可能的:视图不会对应于任何连续的内存块。 Does Boost provide a mechanism to deal with this, or do I need to implement a solution by hand? Boost 是否提供了一种机制来处理这个问题,还是我需要手动实现一个解决方案?

Luckily, the multi_array concept does not require any continuous block of memory.幸运的是,multi_array 概念不需要任何连续的内存块。 The fact that the reference implementation stores a stride for every dimension gives enough information to iterate correctly over the view.参考实现为每个维度存储一个步幅这一事实提供了足够的信息来正确地遍历视图。 In fact, the multi_array concept requires the returned view to be iterable like a standard container.实际上,multi_array 概念要求返回的视图像标准容器一样可迭代。

Unfortunately no, Boost.MA doesn't give a way to iterate over all elements of a view generically.不幸的是,Boost.MA 并没有提供一种方法来一般地迭代视图的所有元素。 As burnpanck said, however you have all the information necessary in the stride information, although that would break the abstraction.正如burnpanck所说,但是您在步幅信息中拥有所有必要的信息,尽管这会破坏抽象。

There are many ways to go through the elements and you didn't specify it (eg canonical order or leading axis first), however you can get an idea on how to iterate over all elements from the example here: https://www.boost.org/doc/libs/1_79_0/libs/multi_array/example/print_array.cpp This technique requires some sort of (template) recursion, terminating in the lower dimension.有很多方法可以遍历元素并且您没有指定它(例如,规范顺序或先导轴),但是您可以从此处的示例中了解如何迭代所有元素: https://www。 boost.org/doc/libs/1_79_0/libs/multi_array/example/print_array.cpp这种技术需要某种(模板)递归,在较低维度终止。

Without worrying too much about performance or details, the technique is the following.无需过多担心性能或细节,该技术如下。

template<class Array, ElementAction action> 
void for_each_element(Array&& arr, ElementAction const& action) {
  for(long i = 0; i != arr.size(); ++i) {
    if constexpr(std::decay_t<Array>::dimensionality != 1) {
       for_each_element(arr[i], action);
    } else {
       action(arr[i]);
    }
  }
}

Use as用于

V = ... array view ..

for_each_element(V, [](auto& e) {e += 1;});

I have written a separate multidimensional array library which as a special accessor to the range of "linearized" elements.我编写了一个单独的多维数组库,它作为“线性化”元素范围的特殊访问器。

V = ...;  // a view
...
for(auto& e : V.elements()) {  // V.elements() has begin() and end()
  e += 1;  // for example
}

which will cover V in the canonical order for arbitrary dimension, even if V is a view with non-trivial strides .它将以规范顺序覆盖任意维度的V即使V是具有非平凡 strides 的视图

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM