Reputation: 3863
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]
Upvotes: 2
Views: 1512
Reputation: 2237
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);
Upvotes: 2
Reputation: 33
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
.
Upvotes: 1