Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 不同大小的数组的数组_C++_Boost_C++11 - Fatal编程技术网

C++ 不同大小的数组的数组

C++ 不同大小的数组的数组,c++,boost,c++11,C++,Boost,C++11,我有一些代码生成一组大小不同但类型相同的tr1::array,如 array<int, 2> array<int, 4> array<int, 6> 数组 排列 排列 这些数组的数量及其大小在编译时给出,因此我确切地知道它们将有多少个,每个数组的大小有多大(但它们可能不同) 问题:我想将它们放在一个集合中(使用数组会很好),但所有成员的类型必须相等,而事实并非如此 我考虑过使用boost::variant,但是如何指定具有编译时确定的类型列表的变量(我考虑

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

array<int, 2>
array<int, 4>
array<int, 6>
数组
排列
排列
这些数组的数量及其大小在编译时给出,因此我确切地知道它们将有多少个,每个数组的大小有多大(但它们可能不同)

问题:我想将它们放在一个集合中(使用数组会很好),但所有成员的类型必须相等,而事实并非如此

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

短暂性脑缺血发作 ~Aki


更正:在这种情况下预处理器不可用。

将不同类型的类放入STL容器的唯一方法是容器包含指向某个基类型的指针(引用不起作用,因为它们不是默认可构造的),并且要收集的对象都继承自该类型。请注意,从基类继承的类型的容器(或任何模板类)不会从基类的容器继承。你可以使用void*但是你需要做很多丑陋和危险的铸造,你必须记得自己释放记忆。为什么不编写一个固定大小的数组类,允许您在构造函数中设置大小?如果您以包装器的形式在araray周围编写,则不应该做太多的工作。如果您想使用基于智能指针的解决方案,请不要尝试使用auto_ptr,因为复制语义对于STL容器来说是错误的-使用类似于boost shared_ptr的方法。

您没有说明为什么需要不同大小的静态大小的数组集合。这很奇怪。为什么不使用动态大小的数组集合

你的选择是:

  • 使用std::vector而不是std::tr1::array

  • 在集合中存储指向数组和数组大小的指针。这可能看起来像:
    std::vector
    。只要确保数组的生存期至少与向量的生存期一样长

  • 我希望boost::variant也能工作,但在实践中使用它会相当麻烦


boost::variant
我会使用boost的MPL和Fusion库。有两种方法可以结束类型列表:生成它们或显式定义它们。前者更灵活一些,但很难说哪一个适合你,因为我们不知道你是如何得到你所拥有的价值的

在任何情况下,生成:

#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;
#包括
#包括
#包括
#包括
#包括
#包括
名称空间bmpl=boost::mpl;
//将索引转换为数组
模板
结构生成数组
{
//或者你有什么计划
静态常数std::size\u t size=t::value*2;
//定义生成的类型
typedef std::数组类型;
};
//要转换的值列表
typedef bmpl::range\u c array\u range;
//将该列表转换为数组和向量
typedef bmpl::transform::type数组_集合;
或明确说明:

#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;
#包括
#包括
#包括
名称空间bmpl=boost::mpl;
//列出所有数组类型
typedef bmpl::vector<
std::数组,
std::数组,
std::数组,
std::数组,
std::数组,
std::数组,
std::数组,
std::数组,
std::数组
>数组集合;
无论哪种方式,您都可以这样使用它:

#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());
}
#包括
#包括
#包括
#包括
#包括
#包括
//融合“融合”MPL和运行时之间的桥梁
名称空间bf=boost::fusion;
结构打印类型
{
模板
void运算符()(常数T&)常数
{

std::cout
std::vector
可能是最简单的。只是不要更改大小。:)无可否认,它不太一样,但很干净。是的,我已经有了一个使用std::vector而不是tr1::array的实现,但是使用动态大小是毫无意义的,因为它们可以在编译时计算出来,所以我正在寻找一个静态解决方案。您可能会喜欢其中一个容器:。此外,如果您想回复某人,请使用@,就像@aasamele@aaa所说的,您需要使用fusion。实际上,我有一个与此类似的问题,它会生成不同类型的数组。MPL似乎是解决方案:)谢谢。我总是很高兴看到关于使用某些imho“高级”(或者只是“新”)像mpl/fusion/proto/phoenix这样的增强库。有时我会看到更多关于伟大用例的帖子(甚至有一些关于这个的问题,但没有太多的答案)。但是谢谢你的例子!