4

In C++ (with or without boost), how can I create an N dimensional vectors where N is determined at runtime?

Something along the lines of:

PROCEDURE buildNVectors(int n)

std::vector < n dimensional std::vector > *structure = new std::vector< n dimensional std::vector >()

END

If passed 1, a vector would be allocated. If passed 2, a 2d nested matrix would be allocated. If passed 3, a 3d cube is allocated. etc.

  • 2
    [multi-dimensional-vector](https://stackoverflow.com/questions/823562/multi-dimensional-vector) – HDJEMAI Apr 12 '17 at 00:38
  • C++ is a statically typed language, without any kind of [reflection](https://en.wikipedia.org/wiki/Reflection_%28computer_programming%29). That means the types, such as the nesting of vectors, will be fixed at time of compilation. If you want a truly dynamic multi-dimensional "vector" you need to implement it yourself or find a library which already has such classes. – Some programmer dude Apr 12 '17 at 00:40
  • Thanks, seems like boost's multi_array is the way to go. – Christopher Harris Apr 12 '17 at 00:47
  • [Boost Multidimensional Array Library](http://www.boost.org/doc/libs/1_39_0/libs/multi_array/doc/user.html) – HDJEMAI Apr 12 '17 at 00:55

1 Answers1

5

Unfortunately you will not be able to do this. A std::vector is a template type and as such it's type must be known at compile time. Since it's type is used to determine what dimensions it has you can only set that at compile time.

The good news is you can make your own class that uses a single dimension vector as the data storage and then you can fake that it has extra dimensions using math. This does make it tricky to access the vector though. Since you will not know how many dimensions the vector has you need to have a way to index into the container with an arbitrary number of elements. What you could do is overload the function call operator operator with a std::intializer_list which would allow you to index into it with something like

my_fancy_dynamic_dimension_vector({x,y,z,a,b,c});

A real rough sketch of what you could have would be

class dynmic_vector
{
    std::vector<int> data;
    int multiply(std::initializer_list<int> dims)
    {
        int sum = 1;
        for (auto e : dims)
            sum *= e;
        return sum;
    }
public:
    dynmic_vector(std::initializer_list<int> dims) : data(multiply(dims)) {}
    int & operator()(std::initializer_list<int> indexs)
    {
        // code here to translate the values in indexes into a 1d position
    }
};

Or better yet, just use a boost::multi_array

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
  • Thanks, definitely considered this route, but don't want to reinvent the wheel if boost or another formidable library out there has an implementation. – Christopher Harris Apr 12 '17 at 00:48
  • 1
    @ChristopherHarris No problem. Just wanted you to know this is not something you can get from just vector alone. – NathanOliver Apr 12 '17 at 00:52