[英]to pass RAII structure as 2D-array into a function
有一個函數,接受2D數組:
void foo ( double ** p )
{ /*writing some data into p*/ }
我不想將原始2D數組傳遞給此函數,因為我不想管理調用new
和delete
內存。 另外,我不想將函數簽名更改為void foo ( std::vector< std::vector<double> >& )
。 而且我不能將foo
作為模板函數(在我的項目中它是一個COM接口方法)。
我想通過一些RAII對象來解析它原始的,就像
void foo ( double * p ){}
std::vectore<double> v(10);
p( &v[0] );
有沒有辦法為2D陣列做到這一點? 我試過了
std::vector< std::vector<int> > v;
foo( &v[0][0] )
和
std::vector< std::tr1::shared_ptr<int> > v;
但我得到編譯錯誤error C2664 - cannot convert parameter
。
另外,在這種情況下,可以確保函數內部的原始地址算術正常嗎?
沒有C ++ 11,2D陣列的大小是已知的。
一種可能的解決方案是改變:
std::vector< std::vector<int> > v;
foo( &v[0][0] )
至
std::vector< std::vector<int> > v;
std::vector<int*> v_ptr;
for (...) {
v_ptr[i] = &v[i][0];
}
foo( &v_ptr[0])
雖然安德烈亞斯已經回答了你的問題,解決了你的特殊問題,但我想指出,雖然這有效,但可能不是你想要做的。
當您使用C ++(而不是更容易使用的語言)時,我假設您關心性能。 在這種情況下,您的方法很可能從一開始就是錯誤的,因為double**
表示數組(或者更確切地說可以表示 )而不是2D數組。 為什么這么糟糕? 因為,就像std::vector< std::vector<int> >
例子一樣,需要多個分配,並且結果內存是非連續的(這對緩存不好),不像double array[N][M]
。
對於2D數組,您實際上應該使用具有索引計算的1D數組,這對緩存更友好。 這當然不允許[x][y]
樣式索引(相反,你必須使用[x+N*y]
或[y+M*x]
,這取決於你選擇的“Fortran order”或“C order” “),但避免了緩存問題,只需要一次分配(和一個簡單的double*
指針)。
如果您正在迭代數組的所有元素
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
}
您甚至可以避免乘法,因為這基本上只是一維迭代,並且會產生額外的2D索引
for(unsigned x = 0, idx = 0; x < N; ++x) for(unsigned y = 0; y < M; ++y, ++idx)
{
p[idx] = bar(x, y);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.