2017-10-05 5 views
2

は私がディメンションを提供した後のboost :: extentオブジェクトのタイプは?

#include <boost/multi_array.hpp> 
using intArray3D = boost::multi_array<int, 3>; 

を持っていると私は同じ形状でintArray3D Sの束を作成したいと:

auto my_shape = boost::extents[3][4][5]; 
intArray3D xs(my_shape), ys(my_shape), zs(my_shape); 

それは変数にboost::extents[3][4][5]を割り当てることautoを使用するのは簡単ですが、どのようにすることができます私は根本的なタイプを具体的に把握していますか?

+1

に記載されていますが好奇心のためにそれを知ってしますか、またはあなたがしたいですかそれで何かをコード化しますか? – Quentin

+1

あなたの場合は、 '' boost :: detail :: multi_array :: extent_gen <3> ''(https://github.com/boostorg/multi_array/blob/83c3738519a442c619f9ef661335acde6878b7d8/include/boost/multi_array/extent_gen.hpp#L28)です。なぜあなたは気にしますか? – Praetorian

+0

@クエンティン両者は少し、実際には。私は、このような 'multi_array'という未知の計算可能なサイズのカップルを必要とするクラスを構築しています。そして、そのような' extent 'をどこかに格納することは、その構築を容易にすると考えました。私がそれを保存すると思っていた方法のどれも(オート以外)働かなかったので、私の好奇心が私に尋ねました! –

答えて

2

documentationは言及:このタイプの発生器はextent_gen::operator[]からRanges連鎖呼び出しの結果を指定するために使用され

template gen_type<Ranges>::type

  • gen_typeboost::multi_array_types::extent_genのメンバーである

(及びboost::multi_array_types::extent_genは、グローバルヘルパーオブジェクトboost::extentsのタイプです)。

エクステントのセットを受け入れるコンストラクタが(少なくともパブリックなドキュメントの目的で)この方法で指定されていることもわかります。 For example

namespace boost { 

template <typename ValueType, 
      std::size_t NumDims, 
      typename Allocator = std::allocator<ValueType> > 
class multi_array { 

...

typedef multi_array_types::extent_gen   extent_gen; 

...

explicit multi_array(extent_gen::gen_type<NumDims>::type ranges, 
         const storage_order_type& store = c_storage_order(), 
         const Allocator& alloc = Allocator()); 

ですからとしてautoを使用せずに、あなたのコード行を書き換えることができます:

boost::multi_array_types::extent_gen::gen_type<3>::type my_shape = 
    boost::extents[3][4][5]; 

これは少しですローカル変数には愚かですが、クラスにエクステントのセットなどを格納したいことがあります。そうであれば、これは正式に文書化されたインターフェースに従ってそれを行う方法です。

(コメントで述べたように、実際の型は、この型定義はboost::internal::が関与して解決するが、それは将来のバージョンで変更される場合がありますので、あなたが、あなたのコード内で「内部」名前空間から何かを使用しないでください。)

+0

私はなぜすべての合併症が必要であるかわかりません。ドキュメントには、コンテナが許可されていることが明示されています。これには 'std :: array <>'のようなものがあります。 'extent_gen'は単なる構文的砂糖の内部型です。 ([私の答え](https://stackoverflow.com/a/46596425/85371)を参照してください) – sehe

+1

それは非常に良い点です。私は 'multi_array'に精通しておらず、エクステント[3] [4] [5]が実際に使用されている配列を見ていないということについてはあまり重視していません。 – aschepler

0
私は多くの配列を作成したいとき、私はその後、

template<class T> 
using factory=std::function< T() >; 

を格納します

auto my_shape = boost::extents[3][4][5]; 
factory<intArray3D> shaper = [my_shape]{ return intArray3D(my_shape); }; 
intArray3D xs(shaper()), ys(shaper()), zs(shaper()); 

これは、電子への依存を解消しますブーストエクステントのxactタイプ。最も重要なこと

3

  1. あなたは
  2. を知っている必要はありませんあなたはextentsはどちらか

多くの物事がいる限り、彼らはdocumented criteriaをacceptible満足している使用する必要はありません。 :

enter image description here

コレクションのコンセプトはthat link

Live On Coliru

#include <boost/multi_array.hpp> 
#include <iostream> 
using intArray3D = boost::multi_array<int, 3>; 

void dump_shape(intArray3D const& arr) { 
    for (unsigned dim = 0; dim < arr.dimensionality; ++dim) 
     std::cout << arr.shape()[dim] << " "; 
    std::cout << "\n"; 
} 

int main() { 
    { 
     auto my_shape = boost::extents[3][4][5]; 
     intArray3D xs(my_shape), ys(my_shape), zs(my_shape); 
     dump_shape(xs); dump_shape(ys); dump_shape(zs); 
    } 

    { 
     std::array<int, 3> my_shape { 3, 4, 5 }; 
     intArray3D xs(my_shape), ys(my_shape), zs(my_shape); 
     dump_shape(xs); dump_shape(ys); dump_shape(zs); 
    } 

    { 
     std::vector<int> my_shape { 3, 4, 5 }; 
     intArray3D xs(my_shape), ys(my_shape), zs(my_shape); 
     dump_shape(xs); dump_shape(ys); dump_shape(zs); 
    } 

} 

プリント

3 4 5 
3 4 5 
3 4 5 
3 4 5 
3 4 5 
3 4 5 
3 4 5 
3 4 5 
3 4 5 
関連する問題