2011-03-01 57 views
2

我試圖做一個函數,它需要一個矩陣作爲輸入並在C++中輸出它的一些函數。但我希望它可以在任意大小的mxn矩陣上工作。即我不能在函數的參數中指定n的值(double matrix [] [n])。因爲n將是任意的。 有沒有什麼辦法可以將任意mxn 2維數組傳遞給函數? 提前感謝您。 -indiajoe如何使一個函數在C++中接收任意大小的多維數組?

+0

http://www.boost.org/doc/libs/release/libs/multi_array/index.html – Anycorn 2011-03-01 17:54:39

+0

http://www.boost.org/doc/libs/1_46_0/libs/numeric/ublas/doc /index.htm – Anycorn 2011-03-01 17:55:20

+0

感謝您的推動圖書館鏈接.. – indiajoe 2011-03-01 19:30:53

回答

7
template <typename T, size_t W, size_t H> 
void foo(T (&array)[W][H]) { 
    // Do stuff with array here 
} 
+0

如何動態矩陣分配? – 2011-03-01 16:44:10

+2

@Eric:爲什麼?這不是必需的。 OP想要一種方式來傳遞具有任意維度的二維數組,這裏是! – 2011-03-01 16:55:36

+0

如果函數的代碼很大,如果調用大量不同大小的矩陣,則可能會導致應用程序代碼大小的巨大增加。並非每個編譯器都足夠智能以合併模板函數。 – 2011-03-01 17:33:46

1

使用標準C++庫,你可以這樣做:

typedef std::vector<double> Dim; 
typedef std::vector<Dim> Matrix; 

void workOnMatrix(Matrix& matrix) 
{ 

} 

編輯:我刪除,因爲SGI的STL引用STL標準C++庫不一樣的東西。看起來非常不同,他們不應該被接受爲另一個。

+0

*抵制敦促去「STL」咆哮* – 2011-03-01 16:37:21

+0

我不喜歡C風格的編碼,所以去STL對我來說沒有問題;) – 2011-03-01 16:56:30

+0

這是一個比Tomalak更好的解決方案。 – 2011-03-01 17:21:32

2

有多種方法可以做到這一點。最好的方法可能是定義一個矩陣類並將一個const引用傳遞給一個實例。

class matrix 
{ 
    double* values; 
    size_t m; 
    size_t n; 
public: 
    matrix(size_t m_, size_t n_) 
    : m(m_), n_(n) 
    { 
     values = new double[m * n]; 
    } 

    ~matrix() 
    { 
     delete[] values; 
    } 

    double& operator(size_t i, size_t j) 
    { 
     assert(i < m); 
     assert(j < n); 
     return values[i + m * j]; 
    } 

    const double& operator(size_t i, size_t j) const 
    { 
     assert(i < m); 
     assert(j < n); 
     return values[i + m * j]; 
    } 
private: 
    matrix(const matrix&); 
    matrix& operator =(const matrix&); 
}; 

void function(const matrix& matrix); 

如果你不想使用一個類,而您的數據存儲線性(在我的矩陣類),您可以將指針簡單地傳遞給了一倍,並且尺寸:

void function(double* values, size_t m, size_t n); 

如果你真的想使用雙[M] [N],並有一個函數接受任何矩陣大小,你可以將其轉換手動雙**,做這樣的事情:

void function(double** lines, size_t m, size_t n); 

void client() 
{ 
    const size_t m = ...; 
    const size_t n = ...; 
    double matrix[m][n]; 

    double* temporary[m]; 
    for (size_t i = 0; i < m; ++ i) { 
     temporary[i] = &matrix[i][0]; 
    } 

    function(temporary, m, n); 
} 

或者,使用模板函數來執行轉換rsion:

void function(double** array, size_t m, size_t n); 

template < size_t M, size_t N > 
void function(double array[M][N]) { 
    double* temporary[M]; 
    for (size_t i = 0; i < M; ++ i) { 
     temporary[i] = &array[i][0]; 
    } 
    function(temporary, M, N); 
} 

這是因爲數組只能衰減一次的指針(即雙[n]的衰減增加一倍*但雙[M] [N]衰減到雙* [n])的。

+0

您的第二個建議是將2d矩陣合併爲一個1d指針數組,似乎是解決我的問題的最簡單方法。非常感謝所有人以各種方式來做到這一點。 – indiajoe 2011-03-01 19:22:32

0

你可以這樣做Tomalak的方式,但我當然不會推薦它。如果數組是通過參數傳遞的,那麼您不能從另一個模板中調用該函數。這意味着幾乎你的整個程序必須是模板化的代碼。好吧,理論上來說,但通常是不切實際的。

你不能使用double**接口,因爲你已經發現了。你可以轉換爲這種類型的,但那麼你還需要在這樣傳遞大小的信息,您可以:

my_ptrptr[row * col_size][col]; 

你必須更明確一些這樣的尺寸,因爲編譯器不再知道它所需要。

你的問題的最佳答案是不這樣做。充分利用STL,這樣你就不必像這樣處理hokey垃圾了。使用Stephane的答案。

然而,你可以做不過,如果你還是要用模板另一件事,就是寫它是通用的:

template < typename Iter > 
void fun(Iter begin, Iter end) 
{ 
    // begin[x][y]... (*begin)[y]...++begin, etc... 
} 
... 
double arr[arr_row_count][arr_col_count]; 
fun(arr, arr+arr_row_count); 

這其中有任何東西,看起來像工作的重大好處一組數組。這意味着它會成爲一種很好的「臨時」方法,您可以使用double[][]類型,直到您可以開始使用更好的產品,如std::vector和/或boost::array。這樣做Tomalak的方式,你將無法在稍後做出這種改變......另一個不使用該方法的原因。

+0

「如果數組是通過參數傳遞的,那麼您永遠無法從另一個模板中調用該函數。」那麼,這完全是無稽之談。究竟是什麼讓你覺得呢?你是否真的在討論只在運行時才知道維數的數組?因爲我的答案當然是關於普通的靜態分配數組,我的函數可以在代碼中的任何上下文中使用。 – 2011-03-01 17:47:29

相關問題