5

Say I have

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

and I want to create a bunch of intArray3Ds with the same shape:

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

It's easy enough to use auto to assign boost::extents[3][4][5] into a variable, but how can I concretely figure out the underlying type?

4

3 回答 3

4

最重要的是,

  1. 你不必知道
  2. 你也不必extents使用

许多事情都是可以接受的,只要它们满足记录的标准

在此处输入图像描述

Collection 概念记录在该链接中

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 
于 2017-10-06T00:00:38.803 回答
3

文档提到:

template gen_type<Ranges>::type

  • 此类型生成器用于指定对 的Ranges链式调用的结果extent_gen::operator[]

wheregen_typeboost::multi_array_types::extent_genboost::multi_array_types::extent_gen也是全局辅助对象的类型boost::extents)的成员。

您还可以看到以这种方式指定了接受一组范围的构造函数(至少出于公共文档的目的)。 例如

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因此,您可以在不使用as的情况下重写该行代码:

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

这对于局部变量来说有点傻,但也许你想在一个类或类似的东西中存储一组范围。如果是这样,这就是根据官方文档接口的方法。

(如注释中所述,此 typedef 解析为的实际类型涉及boost::internal::,但您不应在代码中使用“内部”命名空间中的任何内容,因为这可能会在未来版本中发生变化。)

于 2017-10-05T23:22:15.570 回答
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());

这消除了对提升范围的确切类型的依赖。

于 2017-10-05T23:24:09.953 回答