2

I have

  float viewerMatrix[4][4] =
    {
      {0.99962944, -0.023989394, -0.012864082, -0.032067116},
      {0.02354476, 0.9991557, -0.033667795, -0.0060634422},
      {0.013660891, 0.033352438, 0.99935031, 0.047027141},
      {   0, 0, 0, 1}
    };

I wanted to store this in a class, and there will be many more of these so I thought putting it in vector is a good idea. I need to convert this array into vector<vector<float>> and then after that push_back into a class member that is of type vector< vector<vector<float>> >.

So, can I initialize vector<vector<float>> with that array? What I tried

vector<vector<float>> floatVector (viewerMatrix);

Does not work.

error: invalid conversion from ‘float (*)[4]’ to ‘std::vector<std::vector<float> >::size_type {aka long unsigned int}’ [-fpermissive]
7
  • Why do you need it to initalize it from the intermediate array? Commented Jun 19, 2016 at 16:03
  • It is the output from other method that I have no control. It output 2 dimensional array and I wanted to store this result in my own class. Commented Jun 19, 2016 at 16:04
  • Well, you need to copy in a loop then, there's no direct conversion available. Commented Jun 19, 2016 at 16:05
  • 1
    No, it's not a good idea to use vector for small fixed-size arrays. Commented Jun 19, 2016 at 16:06
  • 1
    std::array would be a better choice. Failing that, roll your own matrix-storage class based on C-style arrays. It's not hard. Commented Jun 19, 2016 at 20:10

2 Answers 2

2

The problem of doing this is a memory layout: two dimensional C array [4][4] is located in memory as 16 (4*4) floats like float[16] array. But vector of vector located in other way: it is more similar like float** dynamic array and every element of type float* is allocated separately. It means you cannot just pass a pointer of your two dimensional array and be good. But you can use STL algorithms.

First of all std::vector and plain C array both are STL compatible. Let's say you need initialize std::vector with one dimentional C array. I must write something like this:

float testArray[4]={0.99962944, -0.023989394, -0.012864082, -0.032067116};
vector<float> testVector(testArray,testArray+4);

It will construct a new vector and iterate from testArray (it's a pointer) to testArray+4 (it's a pointer too) and push_back every element into testVector. So the easiest way to achieve what you want is:

vector<vector<float>> floatVector{
    {viewerMatrix[0],viewerMatrix[0]+4},
    {viewerMatrix[1],viewerMatrix[1]+4},
    {viewerMatrix[2],viewerMatrix[2]+4},
    {viewerMatrix[3],viewerMatrix[3]+4},
};

Of course 4 value in dimensions can be changed so it is better to create a function that takes a two dimensional array of any number of elements and returns std::vector<std::vector<float>>. For example:

template<size_t M,size_t N>
std::vector<std::vector<float>> initVectorWithTwoDimArray(float (&ar)[M][N]){
    std::vector<std::vector<float>> res;
    res.reserve(M);
    for(auto i=0;i<M;++i){
        res.emplace_back(ar[i],ar[i]+N);
    }
    return std::move(res);
}

float viewerMatrix[4][4] =
{
    {0.99962944, -0.023989394, -0.012864082, -0.032067116},
    {0.02354476, 0.9991557, -0.033667795, -0.0060634422},
    {0.013660891, 0.033352438, 0.99935031, 0.047027141},
    {   0, 0, 0, 1}
};

auto floatVector=initVectorWithTwoDimArray(viewerMatrix);

Now floatVector is std::vector of std::vector<float> contained your two dim array.

Edit

If you like this function it can be recreated with array of any type not just float:

template<class T,size_t M,size_t N>
std::vector<std::vector<T>> initVectorWithTwoDimArray(T (&ar)[M][N]){
    std::vector<std::vector<T>> res;
    res.reserve(M);
    for(auto i=0;i<M;++i){
        res.emplace_back(ar[i],ar[i]+N);
    }
    return std::move(res);
}

This version will work for any type of arrays: int, double, AnyYourClass etc. Usage is the same:

float viewerMatrix[4][4] =
{
    {0.99962944, -0.023989394, -0.012864082, -0.032067116},
    {0.02354476, 0.9991557, -0.033667795, -0.0060634422},
    {0.013660891, 0.033352438, 0.99935031, 0.047027141},
    {   0, 0, 0, 1}
};

auto floatVector=initVectorWithTwoDimArray(viewerMatrix);
Sign up to request clarification or add additional context in comments.

Comments

1

You cannot have vector of array. If you really need to store the output in the vector, I would say make a something like

class Matrix
{
float m[4][4];
};

And then copy your stuff over and push it into the vector.

2 Comments

Why not std::array<std::array<float,4>,4> m;?
I just prefer c-style arrays in this case. From what I know there should not be any performance penalties when using container.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.