0

boost::multi_array が提供するビュー機能の使用方法を理解したい。具体的には、初期マトリックスの特定のサブマトリックス (必ずしも連続的ではない) を表すビューのすべての要素を 1 つのループ内で反復処理できるようにしたいと考えています。提供されたイテレータは、私が望むことをしないようです (または何もコンパイルしません)。

次の例では、2x6 マトリックスがあり、その 2x4 サブマトリックスを取得したいので、それを印刷しようとすると、「BoosLion」を取得することが期待されます。実際、これは、次元ごとに繰り返す場合に当てはまります。しかし、単一の反復子で反復を実行しようとすると、プログラムはコンパイルされません。

#include <boost/multi_array.hpp>
#include <iostream>


int main()
{
  boost::multi_array<char, 2> a{boost::extents[2][6]};

  a[0][0] = 'B';
  a[0][1] = 'o';
  a[0][2] = 'o';
  a[0][3] = 's';
  a[0][4] = 't';
  a[0][5] = '\0';

  a[1][0] = 'L';
  a[1][1] = 'i';
  a[1][2] = 'o';
  a[1][3] = 'n';
  a[1][4] = 's';
  a[1][5] = '\0';
  typedef boost::multi_array<char, 2>::array_view<2>::type array_view;
  typedef boost::multi_array_types::index_range range;
  array_view b = a[boost::indices[range{0,2}][range{0,4}] ];

  for (unsigned int i = 0; i < 2; i++ ) {
    for (unsigned int j = 0; j < 4; j++ ) {
      std::cout << b[i][j] << std::endl;
    }
  }
//  I want to do something like this:
//  for (auto itr = b.begin(); itr < b.end(); ++itr) {
//    std::cout << *itr << std::endl;
//  }
}

単一のループだけで反復する方法を知っている人はいますか? ドキュメントを検索してみましたが、関連するものは見つかりませんでした。また、これを行うことができる別のライブラリを誰かが知っている場合は、お知らせください。

4

2 に答える 2

3

これを行う 1 つの方法を次に示します。

#include <iostream>
#include <boost/multi_array.hpp>

// Functor to iterate over a Boost MultiArray concept instance.
template<typename T, typename F, size_t Dimensions = T::dimensionality>
struct IterateHelper {
   void operator()(T& array, const F& f) const {
      for (auto element : array)
         IterateHelper<decltype(element), F>()(element, f);
   }
};

// Functor specialization for the final dimension.
template<typename T, typename F>
struct IterateHelper<T, F, 1> {
   void operator()(T& array, const F& f) const {
      for (auto& element : array)
         f(element);
   }
};

// Utility function to apply a function to each element of a Boost
// MultiArray concept instance (which includes views).
template<typename T, typename F>
static void iterate(T& array, const F& f) {
   IterateHelper<T, F>()(array, f);
}

int main() {
   boost::multi_array<char, 2> a{boost::extents[2][6]};

   a[0][0] = 'B';
   a[0][1] = 'o';
   a[0][2] = 'o';
   a[0][3] = 's';
   a[0][4] = 't';
   a[0][5] = '\0';

   a[1][0] = 'L';
   a[1][1] = 'i';
   a[1][2] = 'o';
   a[1][3] = 'n';
   a[1][4] = 's';
   a[1][5] = '\0';

   typedef boost::multi_array<char, 2>::array_view<2>::type array_view;
   typedef boost::multi_array_types::index_range range;
   array_view b = a[boost::indices[range{0,2}][range{0,4}] ];

   // Use the utility to apply a function to each element.
   iterate(b, [](char& c) {
      std::cout << c << std::endl;
   });

   return 0;
};

上記のコードはiterate()、Boost MultiArray の概念 (ビューを含む) を満たすオブジェクトと、各要素に適用する関数を渡すユーティリティ関数を定義します。ユーティリティ関数は、各次元を再帰的に反復する Functor を使用して機能します。

コリール

于 2016-03-14T00:22:18.763 に答える