简体   繁体   English

(相对)C ++中的尺寸安全包装的STL容器

[英](Relatively) Size-Safe Wrapped STL Container in C++

Bear with me because I'm self taught in C++ and am spending my limited extra time on the job to try to learn more about it (I'm a chemical engineering researcher by day). 忍受我,因为我是用C ++自学的,并花了有限的额外时间在工作上,以尝试学习更多(我每天都是化学工程研究人员)。

I have a pretty simple objective: 1. Make a size-safe container to store a long list of floats. 我有一个非常简单的目标:1.制作一个尺寸安全的容器来存储一长串浮标。 2. Make a specialized version of that container that acts as a matrix. 2.制作该容器的专用版本,使其充当矩阵。

What I've come up with thus far, based on some feedback on various questions I've posed here is: 到目前为止,根据我在这里提出的各种问题的反馈,我得出的结论是:

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;
  }

};

With this implementation I tried to: 通过此实现,我尝试:
1. Present the user of the wrapper with two options for access (".get(x,y)" and "[x][y]") 1.向包装器的用户显示两个访问选项(“ .get(x,y)”和“ [x] [y]”)
2. Maximize reuse by having a based wrapped class and then inheriting it to make the matrix. 2.通过具有一个基础包装类,然后继承它来构成矩阵,从而最大程度地提高重用性。
3. Solve the problem of transitioning from a vector to a deque if the continuous memory limit is hit. 3.解决如果达到连续存储限制,则从向量过渡到双端队列的问题。

Does this seem like a decent solution? 这似乎是一个不错的解决方案吗? Suggestions? 建议?

Have you looked at Boost::Matrix ? 您是否看过Boost :: Matrix There's a lot of numeric and linear algebra things already built within that library. 该库中已经建立了许多数字和线性代数的东西。

EDIT: 编辑:

After reading your comment about transitioning from a vector to a deque when size limits are reached, go with deque . 阅读有关在达到大小限制时从向量过渡到双端队列的评论后,请使用deque Getting "fancy" like that is slowing your productivity down. 像这样“花哨”会降低您的生产率。 Focus on the problem at hand and let the collection worry about the memory. 专注于眼前的问题,让收藏担心内存。 Deque is quite fast for large arrays and only suffers when you release memory in comparison to vector. 对于大型数组,双端队列非常快,并且与向量相比,只有在释放内存时才会受到影响。

Transitioning between the two during a single usage seems unlikely to be worth the effort, to me. 在我看来,在一次使用中在两者之间进行过渡似乎不值得付出努力。

If you want to do this via roll your own, you could define a second template parameter that allows the container type to be specified at compile-time. 如果要自己滚动,则可以定义第二个模板参数,该参数允许在编译时指定容器类型。 Then you would not need both vector and deque as members and the type switching code goes away. 然后,您既不需要vector也不需要deque作为成员,并且类型切换代码也就消失了。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM