Pass nested C++ vector as built-in style multi-dim

2019-07-13 00:20发布

If I have a vector in C++, I know I can safely pass it as an array (pointer to the contained type):

void some_function(size_t size, int array[])
{
    // impl here...
}

// ...
std::vector<int> test;
some_function(test.size(), &test[0]);

Is it safe to do this with a nested vector?

void some_function(size_t x, size_t y, size_t z, int* multi_dimensional_array)
{
    // impl here...
}

// ...

std::vector<std::vector<std::vector<int> > > test;
// initialize with non-jagged dimensions, ensure they're not empty, then...
some_function(test.size(), test[0].size(), test[0][0].size(), &test[0][0][0]);

Edit:

If it is not safe, what are some alternatives, both if I can change the signature of some_function, and if I can't?

8条回答
贼婆χ
2楼-- · 2019-07-13 00:50

Short answer is "no".

Elements here std::vector<std::vector<std::vector<int> > > test; are not replaced in contiguous memory area.

查看更多
做自己的国王
3楼-- · 2019-07-13 00:53

Is it safe to do this with a nested vector?

Yes, IF you want to access the inner-most vector only, and as long you know the number of elements it contains, and you don't try accessing more than that.

But seeing your function signature, it seems that you want to acess all three dimensions, in that case, no, that isn't valid.

The alternative is that you can call the function some_function(size_t size, int array[]) for each inner-most vector (if that solves your problem); and for that you can do this trick (or something similar):

void some_function(std::vector<int> & v1int)
{
    //the final call to some_function(size_t size, int array[]) 
    //which actually process the inner-most vectors
    some_function(v1int.size(), &v1int[0]);
}
void some_function(std::vector<std::vector<int> > & v2int)
{
    //call some_function(std::vector<int> & v1int) for each element!
    std::for_each(v2int.begin(), v2int.end(), some_function);
}

//call some_function(std::vector<std::vector<int> > & v2int) for each element!
std::for_each(test.begin(), test.end(), some_function);
查看更多
不美不萌又怎样
4楼-- · 2019-07-13 00:56

You can only expect multi_dimensional_array to point to a contiguos memory block of size test[0][0].size() * sizeof(int). But that is probably not what you want.

查看更多
时光不老,我们不散
5楼-- · 2019-07-13 00:56

It would be much safer to pass the vector, or a reference to it:

void some_function(std::vector<std::vector<std::vector<int>>> & vector);

You can then get the size and items within the function, leaving less risk for mistakes. You can copy the vector or pass a pointer/reference, depending on expected size and use.

If you need to pass across modules, then it becomes slightly more complicated.

查看更多
狗以群分
6楼-- · 2019-07-13 01:04

A very simple solution would be to simply copy the contents of the nested vector into one vector and pass it to that function. But this depends on how much overhead you are willing to take.

That being sad: Nested vectorS aren't good practice. A matrix class storing everything in contiguous memory and managing access is really more efficient and less ugly and would possibly allow something like T* matrix::get_raw() but the ordering of the contents would still be an implementation detail.

查看更多
爷的心禁止访问
7楼-- · 2019-07-13 01:05

Simple answer - no, it is not. Did you try compiling this? And why not just pass the whole 3D vector as a reference? If you are trying to access old C code in this manner, then you cannot.

查看更多
登录 后发表回答