2013-05-14 36 views
3

我使用C庫以Foo **的形式在2D數組上運行。我在C++代碼中使用它,所以我需要某種包裝。使用1D數組很簡單,因爲矢量迭代器只是指針,但在2D的情況下它變得更加複雜。是否可以在不復制數據的情況下爲Foo **創建一個包裝?如何在C++代碼中包裝C二維數組(Foo **)?

+0

你想爲C庫提供一個STL容器(將其轉換爲'Foo **'),還是想用'Foo **'構建一個STL容器? – zakinster 2013-05-14 11:25:53

回答

3

vector<Foo>的元素存儲在一個動態分配的連續內存中,因此您可以像第一種情況那樣獲取數組的指針Foo*

但是,嵌套向量vector<vector<Foo> >的元素沒有存儲爲連續的二維數組,因此無法直接獲取Foo**

你可以嘗試這樣的事:

vector<vector<Foo> > data; 
vector<Foo*> data_rows; 
for(auto it = data.begin(); it != data.end(); ++it) { 
    //in c++11, you can use data() instead of casting begin() 
    data_rows.push_back(it->data()); 
} 
Foo** c_data = data_rows.data(); 

你沒有複製數據,只是行指針的方式。

+0

Yuou應該使用'vector '作爲目標,而不是使用malloc分配的內存,這更像C++ y。然後你可以用'vec.data()'來獲得'Foo **'。 – jleahy 2013-05-14 11:44:59

+0

@jleahy好點。 – zakinster 2013-05-14 11:53:53

1

我會建議構建一個覆蓋operator []的類,該類在內部保存C指針Foo **。

例如爲:

template <class T> 
class Mat<T> { 
private: T** ptr; int n; int m; //< 2D array is of size n x m 
public: Mat(int n, int m) : n(n), m(m) {} 
Col<T> operator[](int k) { assert(k<n); return Col<T>(*(ptr+k*n)); } 
T& get(int k, int i) { return *(*(ptr+k*n)+i); } 
} 

具有確定的

template <class T> 
class Col<T> { private: T* ptr; 
public: T& operator[](int i) { return *(ptr+i); } 
Col<T>(T* ptr) : ptr(ptr) { } 
} 

的代碼可能不是100%正確的,但我希望你明白了吧,可以重新實現它。 還要確保pointerdata的livetime超過你的C++包裝(也包裝c庫的refcount機制?)。 的operator[]的好聽點是,現在你可以使用它像:

Foo** ptr = from_some_c_library(); 
Mat<Foo> mat(ptr,3,4); 
Foo& element_at_2_2 = mat[2][2]; 
assert(mat.get(2,2) == mat[2][2]); 

請注意,您可能要實現自定義的迭代器Mat<T>,使其與STL職能的工作。