C++ as in Java?: 具有 *variable* int 长度的向量向量

Posted

技术标签:

【中文标题】C++ as in Java?: 具有 *variable* int 长度的向量向量【英文标题】:C++ as in Java?: vector of vectors with *variable* length of int 【发布时间】:2009-11-16 14:36:30 【问题描述】:

我的模型最好使用一些

v int[30][i][N_i];

结构是 30 个整数元组向量,其中

v[0] 是一个假人, v[1] 是普通整数(其中 N_0 个), v[2] 是 int 对(N_1 对) ... v[29] 将是 29 个 int 元组(其中 N_29 个)

不是 vector<vector<int>> 就像在“generic-vector-of-vectors-in-c”中一样

显然,外部固定的dim=30没有问题,内部的由自扩展STL向量类处理。

有没有办法让中间维度固定,但不是恒定的?

【问题讨论】:

您是在尝试实际使用 STL std::vector 类,还是本机 C++ 数组? 不确定我是否理解这个问题。你的意思是像tuple<dummy, vector<int>, vector<int[2]>, ..., vector<int[29]> (或者,如果 N_0,...,N29 是常量:tuple<dummy, int[N_0], int[2][N_1], ..., int[29][N_29])? 问题的标题是“...as in Java”:也许解释一下你将如何在 Java 中做到这一点可以帮助我们理解。 我也觉得解释有混淆,v[2]应该有N_1对吧?在那种情况下,我会说声明实际上是v[30][N_i][i]... 【参考方案1】:

正如我在对您的问题的评论中所写的那样,我不确定您在寻找什么(顺便说一句,我对“as in Java”部分非常感兴趣)。

但由于我认为使用 Boost.MPL(以及 Fusion... 和 Array)生成它会很有趣,我假设您想要一个静态定义的结构,其Ntn 元素是大小为 N 的 int 数组的向量:

#define FUSION_MAX_VECTOR_SIZE 30

#include <boost/mpl/transform.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/inserter.hpp>
#include <boost/mpl/range_c.hpp>
#include <boost/mpl/size_t.hpp>

#include <boost/fusion/include/mpl.hpp>
#include <boost/fusion/include/at_c.hpp>
#include <boost/fusion/include/as_vector.hpp>

#include <boost/array.hpp>

#include <vector>


namespace bf = boost::fusion;
namespace bmpl = boost::mpl;

// Type generator used for elements 2..N
// For those elements, the type of the n'th element is
// std::vector<boost::array<int, n>>
template<class SizeT>
struct VectorOfArray

    typedef std::vector<boost::array<int, SizeT::type::value> > type;
;

// The dummy type used for the first element
struct Dummy;

// The container itself
template<size_t Size>
struct StrangeContainer


    // Define a fusion::vector (this is, more or less, equivalent to a tuple)
    // of "Size" elements, where:
    // - the type of element 0 is Dummy, 
    // - the type of element 1 is vector<int>
    // - the type of the n'th element is vector<array<int, n>>
    typedef typename bf::result_of::as_vector<
        typename bmpl::transform<
            bmpl::range_c<size_t, 2, Size>,
            VectorOfArray<bmpl::_1>,
            bmpl::back_inserter<
                bmpl::vector<Dummy, std::vector<int> >
            >
        >::type
    >::type ContentsType;

    // Helper struct to compute the return type of the "At()" member
    template<size_t I>
    struct ElemType
    
        typedef typename VectorOfArray<bmpl::size_t<I> >::type type;
    ;

    // Specialize "At()"'s return type for element 1
    template<>
    struct ElemType<static_cast<size_t>(1)>
    
        typedef std::vector<int> type;
    ;

    // Specialize "At()"'s return type for element 0
    template<>
    struct ElemType<static_cast<size_t>(0)>
    
        typedef Dummy type;
    ;

    // Get the I'th element
    template<size_t I>
    typename ElemType<I>::type& 
    At()
    
        return bf::at_c<I>(m_Contents);
    

    // The fusion vector holding the elements
    ContentsType m_Contents;
;

int main()

    StrangeContainer<30> s;
    Dummy& d = s.At<0>();
    s.At<1>().push_back(1);
    s.At<2>().push_back(boost::array<int, 2>());
    s.At<3>().push_back(boost::array<int, 3>());
    s.At<29>().push_back(boost::array<int, 29>());
    s.At<29>()[0][0] = 1234;

    return 0;

【讨论】:

【参考方案2】:

最好的方法是围绕向量访问器编写包装函数。包装现有行为的最佳方法是编写一个新类,该类使用您喜欢的向量实现。

【讨论】:

【参考方案3】:

我是 Michael(最初的作者),现在拥有 ID La-AIDA

首先,谢谢大家,Boost & Fusion 对我来说是新手。

致埃里克: 一个错字:v[1] 应该有 N_1 个条目,v[2] N_2 等等。 我想要类似 STL 的东西,而不是 C 数组(缺少边界检查,没有添加它的选项)。

对 Éric 的新评论: 我尝试了您的解决方案,它立即起作用(几乎是在删除虚拟查询之后)! 谢谢! 但是:我需要类似的东西

 for (i = 1;i < 30;i++) 
    cout << s.At<i>[0] << endl; 
 

也就是说,At<..> 的索引应该是可变的(这就是重点,能够运行索引而不是分别处理 30 个硬编码的东西) 但 gcc 报错:“i”不能出现在常量表达式中

关于“在 Java 中”: AfaIk,Java 中的二维矩阵不是一些 诠释 v[10][10]; 具有固定尺寸,但类似于 诠释[][] v; 你第一次有一个

v = new int[10][];

(或类似的语法)然后,这就是重点:

v[0] = new int[1];
...
v[9] = new a[10];

它可以生成一个三角矩阵,当然也可以是你喜欢的任何形式。 事实上,一个常规的 10×10 矩阵也需要 1 加 10 个新矩阵。

关于结构本身: 一个等效的数据结构是

vector<int> v1;
vector<pair<int,int>> v2;
vector<int,int,int> v3;
...
vector<int[29]> v29;

然而,我们必须分别处理这 30 个部分。

我想说v[5][3][123] = 99; 将第 123 个 5 元组中的第 3 个组件设置为 99,而不定义

vector<int> v[30][30];

这可以解决问题,但会浪费大量空间,因为 v[1][2..30][0..\infty] or more generally v[i][i+1..30][*] 从未使用过。

所以,在我的问题中,我有一个 int 列表、另一个对、三元组、...、30 个 int 元组的列表,它们都应该是可排序的等,在一个结构中,不会浪费空间.

【讨论】:

一个小问题:您应该编辑您的问题,而不是发布“答案”。这样更容易找到,并且会将答案分组为答案,而不是答案和问题的混合。 是的 ;-) 我以“匿名迈克尔”的身份问,我的问题不再是我的问题了,可能没有人可以编辑它(除了网站维护者等)。 At&lt;&gt; 的索引必须是常量,因为At 的返回类型是索引的函数。但是,您可以使用 boost::fusion::for_each 迭代 Fusion 序列的元素。 很抱歉,我仍然没有得到“as in Java”部分。事实上,我并不清楚你在追求什么。你提到“int[][]”(一个int数组的数组),然后说一个更复杂的结构“vector,vector>,vector ...vector”(类似于我在回答中描述的内容,但混合了元组和数组),最后是关于“vector[30][30]”(数组的数组向量)。我很困惑:(

以上是关于C++ as in Java?: 具有 *variable* int 长度的向量向量的主要内容,如果未能解决你的问题,请参考以下文章

来自 Textinput 的 Flash as3 比较

如何序列化/反序列化(JSON)ArrayLIst wich has an ArrayLIst as field in Java

as3里面的dictionary的遍历

What would be the closest equivalent in Java to a Micro ORM such as Dapper, PetaPoco, Massive or Cod

java@ What are C++ features missing in Java

Java中的默认值和初始化