容器的boost ::同类型的multi_array,但不同的dimentionality [英] Container for boost::multi_array of same type but with different dimentionality

查看:225
本文介绍了容器的boost ::同类型的multi_array,但不同的dimentionality的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要的是创建一个类,可容纳的boost ::同一类型,但不同的dimentions的multi_array

What i need is to create a class that can hold boost::multi_array of same type but with different dimentions

假定有双人的一个或多个这样的阵列

assume there are one or more such arrays of Double

boost::multi_array<double, 2> array_2d; //2D array
boost::multi_array<double, 3> array_3d; //4D array
boost::multi_array<double, 4> array_4d; //5D array
etc...

我需要一个容器类,它可以容纳所有上述类型需要的时候,能够后来服从正确类型的

i need a container class that can hold all of the above types that is able to deference the correct type later when needed

GenericArray<double> arr;
arr.IsEmpty() // check if it has valid ref
arr.assign(array_2d); //set reference to

然后使用某种模板逻辑找回参考阵列

then get back the reference to the array using some sort of template logic

try{
    boost::multi_array<double, 2>& array_2d_ref = arr.get<2>
    //OR
    boost::multi_array<double, 2>& array_2d_ref = arr.get<multi_array<double, 2>>
    // First one look cleaner tho
}catch (ArrayDimentinalityMismatch e){

}

在同一code座

arr.assign(array_3d);

try{
    boost::multi_array<double, 2>& array_3d_ref=arr.get<multi_array<double, 3>>
}catch (ArrayDimentinalityMismatch e){

}

这可能使用模板?

Is This possible using templates?

推荐答案

首先,我想你可能需要重新评估你的设计。像仿函数,它很少需要code半刚性包装类型在你的泛型类型参数。

Firstly, I think you may want to evaluate your design. Like with functors, it's rarely required to code semi-rigid type wrappers around your generic type arguments.

不过,如果你发现你有一个需要这个,这是一个使用的boost ::变种解决方案:

However, if you do find you have a need for this, here's a solution that uses boost::variant:

template <typename T>
struct GenericArray
{
    template <size_t N> using array_t = boost::multi_array<T, N>;

    template <typename Rhs> GenericArray& operator=(Rhs&& rhs) {
        _storage = std::forward<Rhs>(rhs);
        return *this;
    }

    template <size_t N> array_t<N>      & get()       { return boost::get<array_t<N> >(_storage); }
    template <size_t N> array_t<N> const& get() const { return boost::get<array_t<N> >(_storage); }

  private:
    typename detail::make_generic_array_storage<T>::type _storage;
};

获取LT;&GT; 成员函数抛出一个的boost :: bad_get 异常,如果你得到了尺寸错误的运行时。

The get<> member function throws a boost::bad_get exception if you get the dimension wrong at runtime.

现在,诀窍是,当然,如何 _storage 实施。我产生超过使用位的升压MPL魔法阵维列表的变种:

Now, the trick is, of course, how _storage is implemented. I generate a variant over a list of array dimensions using a bit of Boost MPL magic:

namespace detail {
    namespace mpl = boost::mpl;

    template <typename T, size_t Mindim = 1, size_t Maxdim = 5>
    struct make_generic_array_storage
    {
        template <size_t N> using array_t = boost::multi_array<T, N>;
        template<typename N> struct to_array_f { typedef array_t<N::value> type; };

        using list = typename mpl::transform<
            mpl::range_c<size_t, Mindim, Maxdim>, 
            to_array_f<mpl::_1>,
            mpl::back_inserter<mpl::vector<> > 
        >::type;

        using type = typename boost::make_variant_over<list>::type;
    };
}

没有什么过于复杂,如果你看它从高位:)

Nothing overly complicated, if you look at it from a high level :)

接下来:小样!看到它的 <大骨节病> 住在Coliru

Next up: demo! See it Live On Coliru

GenericArray<double> arr;
arr = array_3d;

try { auto& ref3 = arr.get<3>(); }
catch (boost::bad_get const& e) { std::cout << "L:" << __LINE__ << " " << e.what() << "\n"; }

try { auto& ref2 = arr.get<2>(); } // this fails
catch (boost::bad_get const& e) { std::cout << "L:" << __LINE__ << " " << e.what() << "\n"; }

arr = array_2d;

try { auto& ref2 = arr.get<2>(); } // this succeeds
catch (boost::bad_get const& e) { std::cout << "L:" << __LINE__ << " " << e.what() << "\n"; }

std::cout << "Done";

打印:

L:58 boost::bad_get: failed value get using boost::get
Done

如预期。

奖金:为了实现在存储变种多个阵列状的操作,看看这里:

Bonus: To implement more array-like operations over the variant storage, have a look here:

  • Generating an interface without virtual functions?
  • How to create a interface for serialization in Boost Serialization?

该触摸关于这一主题

这篇关于容器的boost ::同类型的multi_array,但不同的dimentionality的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆