簡體   English   中英

將RAII結構作為2D數組傳遞給函數

[英]to pass RAII structure as 2D-array into a function

有一個函數,接受2D數組:

void foo ( double ** p ) 
{ /*writing some data into p*/ }

我不想將原始2D數組傳遞給此函數,因為我不想管理調用newdelete內存。 另外,我不想將函數簽名更改為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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM