简体   繁体   English

矢量的变量类型向量

[英]vector of variable type vectors

I am currently implementing a data storage for a large table in C++. 我目前正在为C ++中的大表实现数据存储。 The table needs to be able to store different data type for each of a variable number of columns. 该表需要能够为每个可变数量的列存储不同的数据类型。

The type and the length of each column are defined and run-time. 定义每列的类型和长度以及运行时。 Because of this, I figured, a vector of pointer to vectors would be the right approach. 因此,我想,向量指针的向量将是正确的方法。 I can however not figure out how to do this with variable data types. 但是,我无法弄清楚如何使用可变数据类型执行此操作。

I looked at How to get a vector of different vectors in C++ but there is not dynamic solution. 我看了如何在C ++中获取不同向量的向量,但没有动态解决方案。

I am open to any other solutions, I don't necessarily need vectors, but the table should be re-sizable at run-time. 我对任何其他解决方案持开放态度,我不一定需要向量,但是表格应该在运行时重新调整大小。

It should look something like this: 它应该看起来像这样:

0  1  2  3    ...
-  -  -  -    -
1  a  0  1.3  ...
2  b  1  2.5  ...
3  c  0  1.5  ...
4  d  0  0.8  ...
5  e  1  1.2  ...
.. .. .. ...  ...

I some people have suggested using boost::any but I am a bit reluctant of this (in terms of efficiency) because the table has to load large packet files from disk. 我有些人建议使用boost :: any但我有点不情愿(在效率方面)因为表必须从磁盘加载大型数据包文件。

The any Class implemented in boost will do what you need. 在boost中实现的任何类都将满足您的需求。

Here is an example how to use it from their website: 以下是如何在其网站上使用它的示例:

#include <vector>
#include <boost/any.hpp>

using boost::any_cast;
typedef std::vector<boost::any> many;

void append_int(many & values, int value)
{
    boost::any to_append = value;
    values.push_back(to_append);
}

void append_string(many & values, const std::string & value)
{
    values.push_back(value);
}

void append_char_ptr(many & values, const char * value)
{
    values.push_back(value);
}

void append_any(many & values, const boost::any & value)
{
    values.push_back(value);
}

void append_nothing(many & values)
{
    values.push_back(boost::any());
}

To store different types in vector is impossible, but if you store pointers without type ( void* ), then you can retype it to any type you want. 在向量中存储不同类型是不可能的,但如果存储没有类型的指针( void* ),则可以将其重新键入任何所需的类型。 If you don't know at runtime what type you are reading, then make struct containing pointer void* and variable to determine type. 如果您在运行时不知道您正在读什么类型,那么使包含指针void *和变量的struct来确定类型。

It's while since I used C++ so example can be just pseudo C++. 因为我使用C ++,所以这个例子可能只是伪C ++。

#include<vector>
#include<iostream>

void workWithCharArray(char* c);

typedef struct mytype {
    int type = 0;   // this defining default values is available since C++11
    void* var = nullptr;
} Mytype;

int main() {
    char* ptr = (char*)"Testing string";
    std::vector<Mytype> container;
    Mytype tostore;
    tostore.type = 1;
    tostore.var = (void*)ptr;

    container.append(tostore);

    switch (tostore.type) {
        case 1:
            workWithCharArray((char*)tostore.var);
            break;
        default:
            std::cerr << "Unknown type - Error handling";
    }

    return 0;
}

void workWithCharArray(char* c) {
    std::cout << c << std::endl;
}

If you cannot use boost and do not want to re-implement boost::any you could use void * as the poor man's any container. 如果你不能使用boost并且不想重新实现boost::any你可以使用void *作为穷人的任何容器。 The table level would be a std::vector<void *> and each column (of type T) would be a std::vector<T> . 表级别是std::vector<void *> ,每列(类型为T)都是std::vector<T> You then allocate each column in turn and store the address of the column in the initial std::vector<void *> . 然后依次分配每个列并将列的地址存储在初始的std::vector<void *>

Provided you cast the value of each column before using it it should work. 如果在使用之前转换每列的值,它应该可以工作。 Depending on your requirements it may be more or less simple to implement that correctly because as you have raw pointers you should implement carefully the destructors and if appropriate copy an move constructors and assignements or declare them deleted. 根据您的要求,正确实现它可能或多或少变得简单,因为当您有原始指针时,您应该仔细实现析构函数,并在适当时复制移动构造函数和分配或声明它们被删除。 But it is a (poor man's) boost alternative... 但这是一个(穷人)提升替代品......

If you need a two-dimensional vector that stores one-dimensional vectors of different data types, you could create an abstract, non-templated base class for the inner vector and then store pointers to that abstract base class in the outer vector, utilising polymorphism if you want to call member functions on the abstract vectors. 如果你需要一个存储不同数据类型的一维向量的二维向量,你可以为内向量创建一个抽象的,非模板化的基类,然后利用多态性在外向量中存储指向该抽象基类的指针。如果你想在抽象矢量上调用成员函数。

class AbstractVector {
    ... // provide pure virtual interface here
}

template<class T>
class MyVector : public AbstractVector, public std::vector<T> { 
    ... /* provide implementation of pure virtual interface using 
           already available functionality from std::vector here */
}

In your implementation you can then store pointers to the base class AbstractVector (or unique_ptrs or shared_ptrs depending on what you want to do): 在您的实现中,您可以存储指向基类AbstractVector (或unique_ptrsshared_ptrs指针,具体取决于您要执行的操作):

std::vector<AbstractVector *> table;
MyVector<int> * columnOne = new MyVector<int>;
MyVector<float> * columnTwo = new MyVector<float>;
table.push_back(columnOne);
table.push_back(columnTwo);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM