(相对)用C ++编写的尺寸安全的STL容器

时间:2010-09-23 18:59:26

标签: c++ templates vector wrapper deque

请耐心等待我,因为我是用C ++自学的,并且在工作上花了我有限的额外时间来尝试更多地了解它(我白天是化学工程研究员)。

我有一个非常简单的目标: 1.制作一个尺寸安全的容器来存储一长串浮子。 2.创建一个充当矩阵的容器的专用版本。

到目前为止,根据我在此提出的各种问题的一些反馈,我得出的是:

template<typename T>
class VectorDeque
{
public:

  void resize_index(unsigned int index) {
    if ( my_container == VECTOR ) {
      try {
        my_vector.resize(index);
        my_container = VECTOR;
      }
      catch(std::bad_alloc &e) {
        my_deque.resize(index);
        my_container = DEQUE;
      }
    }
    else if ( my_container == DEQUE ) {
      my_deque.resize(index);
    }
  }

  T operator[](unsigned int index) { 
    T ret_val;
    if ( STORAGE_CONTAINER == VECTOR ) {
      ret_val = my_vector[index];
    }
    else if ( STORAGE_CONTAINER == DEQUE ) {
      ret_val = my_deque[index];
      }
  }
private:
  enum STORAGE_CONTAINER { NONE, DEQUE, VECTOR };

  std::vector<T> my_vector;
  std::deque<T> my_deque;
  STORAGE_CONTAINER my_container;

  T& get(int index) { 
    T temp_val;
    if(my_container == VECTOR) {
      temp_val = my_vector[index];
    }
    else if(my_container == DEQUE) {
      temp_val = my_deque[index];
    }

    return temp_val;
  }

};

template<typename T>
class VectorDeque2D: public VectorDeque<T>
{
public:

  template<typename T>
  class VectorDeque2D_Inner_Set
  {
    VectorDeque2D& parent;
    int   first_index;
  public:
    // Just init the temp object
    VectorDeque2D_Inner_Set(My2D& p, int first_Index) : 
      parent(p), 
      first_Index(first_index) {} 
    // Here we get the value.
    T& operator[](int second_index)  const 
    { return parent.get(first_index,second_index);}   
  };

  // Return an object that defines its own operator[] that will access the data.
  // The temp object is very trivial and just allows access to the data via 
  // operator[]
  VectorDeque2D_Inner_Set<T> operator[](unsigned int first_index) { 
    return  VectorDeque2D_Inner_Set<T>(*this, first_index);
  }

  void resize_index_second(unsigned int second_index) {
    if ( my_container == VECTOR ) {
      try {
        for (unsigned int couter=0;couter < my_vector.size(); counter++) {
          my_vector[counter].resize(second_index);
        }
        my_container = VECTOR;
      }
      catch(std::bad_alloc &e) {
        for (unsigned int couter=0;couter < my_deque.size(); counter++) {
          my_deque[counter].resize(second_index);
        }
        my_container = DEQUE;
      }
    }
    else if ( my_container == DEQUE ) {
      for (unsigned int couter=0;couter < my_deque.size(); counter++) {
        my_deque[counter].resize(second_index);
      }
    }
  }

  void resize(unsigned int first_index,
          unsigned int second_index) {
    if ( my_container == VECTOR ) {
      try {
        my_vector.resize(first_index);
        for (unsigned int couter=0;couter < my_vector.size(); counter++) {
          my_vector[counter].resize(second_index);
        }
        my_container = VECTOR;
      }
      catch(std::bad_alloc &e) {
        my_deque.resize(first_index);
        for (unsigned int couter=0;couter < my_deque.size(); counter++) {
          my_deque[counter].resize(second_index);
        }
        my_container = DEQUE;
      }    
    }
    else if ( my_container == DEQUE ) {
      my_deque.resize(first_index);
      for (unsigned int couter=0;couter < my_deque.size(); counter++) {
        my_deque[counter].resize(second_index);
      }
    }
  }
private:
  enum STORAGE_CONTAINER { NONE, DEQUE, VECTOR };

  friend class VectorDeque2D_Inner_Set;

  std::vector<std::vector<T> > my_vector;
  std::deque<std::deque<T> > my_deque;
  STORAGE_CONTAINER my_container;

  T& get(int first_index,int second_index) { 
    T temp_val;
    if(my_container == VECTOR) {
      temp_val = my_vector[first_index][second_index];
    }
    else if(my_container == DEQUE) {
      temp_val = my_deque[first_index][second_index];
    }

    return temp_val;
  }

};

通过这个实现,我试图:
1。向包装的用户提供两个访问选项(“.get(x,y)”和“[x] [y]”)) 2。通过使用基于包装的类然后继承它以生成矩阵来最大化重用。
3. 如果达到连续内存限制,解决从向量转换为双端队列的问题。

这看起来像是一个不错的解决方案吗?建议?

2 个答案:

答案 0 :(得分:2)

你看过Boost::Matrix了吗?在该库中已经构建了许多数字和线性代数。

编辑:

在阅读有关在达到大小限制时从向量转换为双端队列的评论后,请使用deque。像这样“花哨”会降低你的生产力。专注于手头的问题,让收藏担心记忆。 Deque对于大型数组来说非常快,并且与向量相比只释放内存时会受到影响。

答案 1 :(得分:0)

对我来说,在单次使用过程中两者之间的转换似乎不值得付出努力。

如果要通过自己的方式执行此操作,可以定义第二个模板参数,该参数允许在编译时指定容器类型。然后,您不需要vectordeque作为成员,类型转换代码就会消失。

template<typename T, typename CONTAINER>
class VectorDeque
{
// snip
private:
  CONTAINER<T> _storage;
};