不同大小的数组的数组 [英] array of arrays of different size

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

问题描述

我有一些代码可以生成一组不同大小但类型相同的tr1 :: array,例如

I've some code that produces a set of tr1::array of different sizes, but same type, like

array<int, 2>
array<int, 4>
array<int, 6>

这些数组的数量及其大小是在编译时给出的,因此我确切地知道它们的数量和每个数组的大小(但它们可能有所不同).

The number of these arrays, and their sizes, are given in compile time, so I know exactly how many of them there will be and how's big each one (but they may be different).

问题:我想将它们放入集合中(使用array<>会很棒),但是所有成员的类型必须相等,而事实并非如此.

Problem: I would like to put them in a collection (using array<> would be great), but type must be equal for all the members and this is not the case.

我考虑过使用boost :: variant,但是如何用编译时确定的类型列表指定一个变量(我正在考虑大量使用预处理器...)? 怎么样使用boost :: any?其他方法? (野生指针?)

I thought about using boost::variant, but how can specify a variant with a compile-time determined list of types (I'm thinking about an heavy usage of the preprocessor...)? What about using boost::any? Other methods? (Wild pointers?)

TIA 〜阿基

更正:在这种情况下不能使用预处理器.

Correction: preprocessor is not usable in this case.

推荐答案

我将使用Boost的MPL和Fusion库.以类型列表结尾的方法有两种:生成它们,或显式定义它们.前者比较灵活,但是由于我们不知道您如何获得所拥有的价值,因此很难说哪一种适合您.

I would use Boost's MPL and Fusion libraries. There are two ways of ending up with the type list: generate them, or explicitly define them. The former is bit more flexible, but it's hard to say which is right for you since we don't know how you get the values you have.

无论如何,都会生成:

#include <boost/mpl/for_each.hpp>
#include <boost/mpl/range_c.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/mpl/vector.hpp>
#include <array>
#include <iostream>

namespace bmpl = boost::mpl;

// turns an index into an array
template <typename T>
struct make_array
{
    // or whatever scheme you have
    static const std::size_t size = T::value * 2;

    // define generated type
    typedef std::array<int, size> type;
};

// list of values to convert
typedef bmpl::range_c<size_t, 1, 10> array_range;

// transform that list into arrays, into a vector
typedef bmpl::transform<array_range, make_array<bmpl::_1>,
                            bmpl::back_inserter<bmpl::vector<>>
                                >::type array_collection;

或明确说明:

#include <boost/mpl/vector.hpp>
#include <array>
#include <iostream>

namespace bmpl = boost::mpl;

// list all array types
typedef bmpl::vector<
            std::array<int, 2>,
            std::array<int, 4>,
            std::array<int, 6>,
            std::array<int, 8>,
            std::array<int, 10>,
            std::array<int, 12>,
            std::array<int, 14>,
            std::array<int, 16>,
            std::array<int, 18>
                > array_collection;

无论哪种方式,您都可以像这样使用它:

Either way, you can then use it like this:

#include <boost/fusion/algorithm.hpp>
#include <boost/fusion/container/vector.hpp>
#include <boost/fusion/mpl.hpp>
#include <boost/fusion/sequence.hpp>
#include <boost/mpl/for_each.hpp>
#include <typeinfo>

// fusion "fuses" the bridge between MPL and runtime
namespace bf = boost::fusion;

struct print_type
{
    template <typename T>
    void operator()(const T&) const
    {
        std::cout << typeid(T).name() << "\n";
    }
};

struct print_values
{
    template <typename T>
    void operator()(const T& pArray) const
    {
        std::cout << "Printing array with size "
                    << pArray.size() << ":\n";
        std::for_each(pArray.begin(), pArray.end(),
                [](int pX)
                {
                    std::cout << pX <<  " ";
                });
        std::cout << std::endl;
    }
};

int main(void)
{
    // print all the types you have
    bmpl::for_each<array_collection>(print_type());
    std::cout.flush();

    // make a usable type out of the typelist
    typedef bf::result_of::as_vector<array_collection>::type array_fusion;
    array_fusion arrays; // now have an array of different arrays,
                         // compile-time generated but run-time usable

    // access like this:
    bf::at_c<0>(arrays)[1] = 5; 
    bf::at_c<1>(arrays)[2] = 7; 
    bf::at_c<2>(arrays)[0] = 135; 

    // for_each:
    bf::for_each(arrays, print_values());
}

这篇关于不同大小的数组的数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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