【问题标题】:How to wrap C 2D arrays (Foo**) in C++ code?如何在 C++ 代码中包装 C 2D 数组(Foo**)?
【发布时间】:2013-05-14 11:01:02
【问题描述】:

我使用了一个 C 库,它以 Foo** 的形式对二维数组进行操作。我在 C++ 代码中使用它,所以我需要某种包装器。对于一维数组,它很简单,因为向量迭代器只是指针,但在二维的情况下,它变得更加复杂。是否可以在不复制数据的情况下为 Foo** 制作包装器?

【问题讨论】:

  • 您想为您的 C 库提供一个 STL 容器(将其转换为 Foo**),还是希望从 Foo** 构建一个 STL 容器?

标签: c++ c stl wrapper


【解决方案1】:

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();

这样你就不会复制数据,只是复制行指针。

【讨论】:

  • 你可能应该使用vector&lt;Foo*&gt;作为目标,而不是使用malloc分配的内存,这有点C++y。然后您可以通过vec.data() 获得Foo**
【解决方案2】:

我建议构建一个覆盖 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% 正确,但我希望您能理解并重新实现它。 还要确保指针数据的生存时间超过您的 c++ 包装器(还包装 c 库的引用计数机制?)。 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&lt;T&gt; 实现自定义迭代器,以使其与 STL 函数一起使用。

【讨论】:

    猜你喜欢
    • 2020-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-03
    • 1970-01-01
    相关资源
    最近更新 更多