C++ 将RAII结构作为2D数组传递给函数

C++ 将RAII结构作为2D数组传递给函数,c++,multidimensional-array,C++,Multidimensional Array,有一个函数,接受二维数组: void foo ( double ** p ) { /*writing some data into p*/ } 我不想将原始2D数组传递到此函数中,因为我不想管理内存调用new和delete。另外,我不想将函数签名更改为void foo(std::vector&)。我不能将foo作为模板函数(在我的项目中,它是一个COM接口方法) 我想通过一些RAII对象来装饰它,比如 void foo ( double * p ){} std::vectore<dou

有一个函数,接受二维数组:

void foo ( double ** p ) 
{ /*writing some data into p*/ }
我不想将原始2D数组传递到此函数中,因为我不想管理内存调用
new
delete
。另外,我不想将函数签名更改为void foo(std::vector&)。我不能将
foo
作为模板函数(在我的项目中,它是一个COM接口方法)

我想通过一些RAII对象来装饰它,比如

void foo ( double * p ){}
std::vectore<double> v(10);
p( &v[0] );
voidfoo(double*p){
标准:vectore v(10);
p&v[0]);
对于二维阵列,有没有办法做到这一点?我试过了

std::vector< std::vector<int> > v;
foo( &v[0][0] )
std::vectorv;
foo(&v[0][0])

std::vectorv;
但我得到编译错误
错误C2664-无法转换参数

另外,在这种情况下,可以确保函数中的原始地址算法正常工作吗


没有C++11,2D数组的大小是已知的。

一种可能的解决方案是更改:

std::vector< std::vector<int> > v;
foo( &v[0][0] )
std::vectorv;
foo(&v[0][0])

std::vectorv;
std::向量v_ptr;
对于(…){
v_ptr[i]=&v[i][0];
}
foo(&v_ptr[0])

虽然Andreas已经回答了您的问题,解决了您的特定问题,但我想指出,尽管这是可行的,但这可能不是您想要做的

因为你使用C++(而不是一个更容易使用的语言),我假设你关心性能。在这种情况下,您的方法从一开始就很可能是错误的,因为

double**
表示数组的数组(或者更确切地说可以表示),而不是2D数组。为什么这么糟糕?因为,与
std::vector
示例一样,需要多次分配,并且生成的内存是非连续的(这对缓存不利),不同于
双数组[N][M]

对于二维数组,实际上应该使用1D数组进行索引计算,这对缓存更为友好。当然,这不允许使用
[x][y]
-风格的索引(相反,您必须使用
[x+N*y]
[y+M*x]
,具体取决于您选择的“Fortran顺序”或“C顺序”),但可以避免缓存问题,只需要一次分配(以及一个简单的
双*
指针)

如果要迭代数组的所有元素,如中所示

for(unsigned x = 0; x < N; ++x) for(unsigned y = 0; y < M; ++y)
{
    unsigned idx = y + M * x;
    p[idx] = bar(x, y); // equivalent to p[x][y] = bar(x,y) in the array-of-arrays case
}
for(无符号x=0;x
您甚至可以避免乘法,因为这基本上只是一个1D迭代,需要额外生成2D索引

for(unsigned x = 0, idx = 0; x < N; ++x) for(unsigned y = 0; y < M; ++y, ++idx)
{
    p[idx] = bar(x, y);
}
for(无符号x=0,idx=0;x
谢谢,至少我的编译器处理它时没有错误!我想知道,你能确定在
foo
中使用地址算法吗?@fogbit是的,这应该可以
for(unsigned x = 0; x < N; ++x) for(unsigned y = 0; y < M; ++y)
{
    unsigned idx = y + M * x;
    p[idx] = bar(x, y); // equivalent to p[x][y] = bar(x,y) in the array-of-arrays case
}
for(unsigned x = 0, idx = 0; x < N; ++x) for(unsigned y = 0; y < M; ++y, ++idx)
{
    p[idx] = bar(x, y);
}