具有动态项目大小的C ++向量

时间:2011-06-09 14:39:11

标签: c++ vector

C ++ STL向量具有很多不错的属性,但只有在运行时知道每个项目的大小时才有效。

我希望有一个在运行时具有动态项目大小的矢量类。

背景:我的项目由一系列整数和双精度组成;一个只在运行时知道的序列。在运行时给矢量赋予每个项目的大小就足够了。

我知道可能的解决方法,但这些不倾向于反映算法的基本思想,这对于维护来说总是一件坏事。是否存在提供这种方便和工作效率的课程?

编辑:

这与整个阵列中不同的项目大小无关。它没有没有。它是在运行时决定数组中的项目有多大;即动态类型的(非常)弱形式,与模板使用的静态类型形成对比。

因此,对象的初始化应如下所示:

DynamicVector V( lengthofvector, sizeofelement );

应用程序是单纯的网格。对象$ V $包含固定大小或“类型”的项目,每个项目由拓扑信息的整数和一些几何信息的双精度组成。甚至可能会有布尔人参与其中,但到目前为止这无关紧要。

9 个答案:

答案 0 :(得分:4)

问题在于,如果您无法在向量中存储每个项目的大小,那么您将永远无法将数据恢复出来。

将所有项目存储为double怎么样?这大大简化了事情。

或者您可以考虑boost::variant

编辑:但是你能真正解释为什么你想要以相同的顺序存储两种不同的类型吗?这有时表明底层设计需要进一步思考。

答案 1 :(得分:1)

您可以使用vector指向序列对象的指针 - 最好是智能指针,以简化向量中的内存管理。

答案 2 :(得分:1)

如果它只是intdouble的序列,那么您只需使用:

 std::vector<double> sequence;

然后将intdouble插入其中。但是,此方法不会跟踪项目的类型。如果类型对您很重要,那么以下内容可能会对您有所帮助:

struct item
{
  union 
  {
     int i;
     double d;
  } data;
  char type; //store 0 for int, 1 for double;
};

std::vector<item> sequence;

当然,这种方法每个项目只需至少一个额外字节,用于存储项目的类型。您可能希望使用#pragma pack技术来挤压额外的填充。

或者更好的是重新设计你的代码,这样你就有两个序列而不是一个:

std::vector<int>     intSeq;
std::vector<double>  doubleSeq;

答案 3 :(得分:0)

vector表示内存中的连续数组。这是有效的,因为它可以使用指针算术来直接通过索引访问元素。但这样做意味着所有元素具有相同的大小,并在构建向量之前知道这个大小。

根据您的需要,使用指向元素的指针向量,双向链表。指针矢量几乎和矢量一样快。它只需要一种模式的尊重。

如果整数和双精度大小相同(例如64位),则可以使用联合作为整数或双精度访问每个项目。但是你需要一种方法来了解每个元素应该是什么。

答案 4 :(得分:0)

如果您不想诉诸变通办法,我认为您应该考虑对这些“动态大小的项目”进行抽象。它的设计应该考虑到它必须在STL向量中使用(然后必须保证一些必要条件),这样你最终可以编写如下内容:

std::vector<DynamicSizedItem> myVector;

答案 5 :(得分:0)

创建一个包含三个向量的类:一个用于整数,一个用于双精度,另一个用于每个项目的条目,以告知相应项目的类型及其在相应向量中的索引。

答案 6 :(得分:0)

使用std :: vector其中item是一个包装的智能指针。 “item”类使指针看起来像一个普通值:

class item {
private:
    boost:unique_ptr<base> p;
public:
    // ...
    public item(item that);

    public int someFunction() {
       // Forwarded
       return p->somefunction();
    }
};

class base {
    virtual ~base();
    // This is needed in order to implement copy of the item class
    virtual base* clone();
};

public item::item(item that) : p(that.p.clone()) {}

class some_real_type() : public base {
   // ....
}

答案 7 :(得分:0)

我认为前进的最佳方式(在性能和可维护性方面)是一种解决方法,将std :: vector和std :: vector包装在两个类中,这些类将公共基类与适当的接口进行交互。

如果你想在运行时动态,那就是如何正确地做到这一点。它还可以帮助您编写有效的代码来处理每个项目,以及简单地(但缓慢地)访问每个元素。

答案 8 :(得分:0)

我之前见过这个问题! Is there an STL container that stores an array of elements in contiguous memory where the element size is specified at runtime?

Guy想要一个“交错的矢量”(他的话),它将保存动态大小的对象,由成员类型和偏移量的地图定义:

typedef Toffset uint; //byte offset;
typedef Ttype   uint; //enum of types
typedef std::pair<Toffset,Ttype> member;
typedef std::unordered_map<std::string, member> memberdefs;

我想出了一个(未经测试的)类来处理它。完整的代码在链接中,但原型是:

class interleaved_vector {
    const char* buffer;
    size_t count;
    size_t size;
    std::shared_ptr<memberdefs> members;
public: 
    class dynamic_object {
        const char* buffer;
        std::shared_ptr<memberdefs> members;
        friend interleaved_vector;
        dynamic_object(const char* buffer_, std::shared_ptr<memberdefs> members_);
        dynamic_object& operator=(const dynamic_object& b) = delete;
    public:
        dynamic_object(const dynamic_object& b) ;
        template <class T>
        T get(const std::string& member) const;
        template <>
        T* get<T*>(const std::string& member) const;
        void* operator[](const std::string& member) const;
    };
    interleaved_vector(const char* buffer_, size_t count_, size_t size_, const memberdefs& members_);
    dynamic_object get(size_t index) const;
    dynamic_object operator[](size_t index) const;
    size_t size();
};

作为警告:它确实依赖于我认为未定义的某些行为,而且一般来说,这是一个坏主意。使用指针向量。