动态分配参差不齐的矩阵

Dynamically allocate ragged matrix

我正在尝试制作一个动态分配二维结构的通用函数。每行中的元素数不必对所有行都相同。结构表示为容器类型,其元素也是容器类型(例如一组列表)。该内部容器的元素类型也可以是任意的。容器仅支持 begin、end 和 size 函数。所有迭代器类型都必须支持迭代器操作。函数应该首先通过连续分配过程动态分配用于存储二维结构的space,然后将其接受的结构的元素重写到动态结构中。函数 returns 一个双指针,通过它可以访问此结构的元素。

#include <iostream>
#include <set>
#include <list>
#include <vector>
template < typename tip >
  auto Make2DStructure(tip mat) {
    using tip_objekta = typename std::decay < decltype(mat[0][0]) > ::type;
    tip_objekta ** dynamic_mat = nullptr;
    int rows = 0, total = 0;
    for (auto i: mat) {
      rows++;
      for (auto j: i)
        total++;
    }
    int columns[rows];
    int k = 0;
    for (auto i: mat) {
      int num_of_colums = 0;
      for (auto j: i)
        num_of_colums++;
      columns[k] = num_of_colums;
      k++;
    }

    try {
      dynamic_mat = new tip_objekta * [rows];
      dynamic_mat[0] = new tip_objekta[total];
      for (int i = 1; i < rows; i++)
        dynamic_mat[i] = dynamic_mat[i - 1] + columns[i];
      for (int i = 0; i < rows; i++)
        for (int j = 0; j < columns[i]; j++)
          dynamic_mat[i][j] = mat[i][j];
    } catch (...) {
      delete[] dynamic_mat[0];
      delete[] dynamic_mat;
      throw std::bad_alloc();
    }
    return dynamic_mat;
  }

int main() {
    std::vector<std::vector<int>>mat{
        {1,2},
        {3,4,5,6},
        {7,8,9}
    };
    int columns[3]={2,4,3};
  try {
    int ** dynamic_mat = Make2DStructure(mat);
    for (int i = 0; i < 3; i++) {
      for (int j = 0; j < columns[i]; j++)
        std::cout << dynamic_mat[i][j] << " ";
      std::cout << std::endl;
    }
    delete[] dynamic_mat[0];
    delete[] dynamic_mat;
  } catch (...) {
    std::cout << "Problems with memory";
  }
  return 0;
}

我如何修改它以在不在 Make2DStrucure() 中建立索引的情况下工作?

此外,如果我在 main 函数中使用 std::set<std::list<int>> 而不是 std::vector<std::vector<int>>,我会遇到推导问题。我如何修改它以适用于不同的外部和内部容器?

这里有一种方法可以完成您想要的:

#include <iterator>
#include <type_traits>

template <typename tip>
auto Make2DStructure(tip&& mat) {
    // create an alias for the value type:
    using value_type = std::decay_t<decltype(*std::begin(*std::begin(mat)))>;

    // allocate memory for the return value, the pointer-pointer:    
    value_type** rv = new value_type*[mat.size()]; // C++17: std::size(mat)

    // Calculate the number of values we need to allocate space for:
    size_t values = 0;
    for(auto& inner: mat) values += inner.size();  // C++17: std::size(inner)
    
    // allocate the space for the values:
    value_type* data = new value_type[values];

    // loop over the outer and inner container and keep the index running:   
    size_t idx = 0;

    for(auto& inner : mat) {
        // assign the outer pointer into the flat data block:
        rv[idx++] = data;
        for(auto& val : inner) {
            // assign values in the data block:
            *data++ = val;
        }
    }

    return rv;
}

在指定的地方使用 std::size,这也适用于普通数组,而不仅仅是容器 类。