【问题标题】:Generic vector of vectors in C++C ++中向量的通用向量
【发布时间】:2008-11-16 15:26:26
【问题描述】:

在 C++ 中有没有一种好方法来实现(或伪造)一个通用向量的类型?

忽略向量向量何时是一个好主意的问题(除非有等效的东西总是更好)。假设它确实准确地建模了问题,并且矩阵没有准确地建模问题。还假设将这些东西作为参数的模板化函数确实需要操纵结构(例如调用 push_back),因此它们不能只采用支持 [][] 的泛型类型。

我想做的是:

template<typename T>
typedef vector< vector<T> > vecvec;

vecvec<int> intSequences;
vecvec<string> stringSequences;

当然这是不可能的,因为 typedef 不能被模板化。

#define vecvec(T) vector< vector<T> >

很接近,并且可以避免在每个在 vecvecs 上运行的模板化函数中重复类型,但不会受到大多数 C++ 程序员的欢迎。

【问题讨论】:

    标签: c++ stl


    【解决方案1】:

    你想要模板类型定义。这在当前的 C++ 中尚支持。解决方法是做

    template<typename T>
    struct vecvec {
         typedef std::vector< std::vector<T> > type;
    };
    
    int main() {
        vecvec<int>::type intSequences;
        vecvec<std::string>::type stringSequences;
    }
    

    在下一个 C++ 中(由于 2010 年称为 c++0x,c++1x),这将是可能的:

    template<typename T>
    using vecvec = std::vector< std::vector<T> >;
    

    【讨论】:

    • 我认为他们还修复了 >> 中对空格的需求
    【解决方案2】:

    我使用在 boost 库中实现的Boost.MultiArray

    HTH

    【讨论】:

      【解决方案3】:

      您可以简单地创建一个新模板:

      #include <string>
      #include <vector>
      
      template<typename T>
      struct vecvec : public std::vector< std::vector<T> > {};
      
      int main() 
      {
          vecvec<int> intSequences;
          vecvec<std::string> stringSequences;
      }
      

      如果你这样做,你必须记住向量的析构函数不是虚拟的,不要做这样的事情:

      void test()
      {
          std::vector< std::vector<int> >* pvv = new vecvec<int>;
          delete pvv;
      }
      

      【讨论】:

      • 你会失去所有方便的vector构造函数。您需要定义它们,只需将参数传递给父级。一种可能性,但不是一个精益求精的解决方案。
      • -1 答案本身结构合理,您指出了所提出解决方案的主要缺陷之一。但是,我认为,这个缺陷和其他缺陷足以让人们投反对票。
      【解决方案4】:

      您可以使用std::vector 作为基础来实现基本的vector-of-vector类型:

      #include <iostream>
      #include <ostream>
      #include <vector>
      using namespace std;
      
      template <typename T>
      struct vecvec
      {
          typedef vector<T> value_type;
          typedef vector<value_type> type;
          typedef typename type::size_type size_type;
          typedef typename type::reference reference;
          typedef typename type::const_reference const_reference;
      
          vecvec(size_type first, size_type second)
              : v_(first, value_type(second, T()))
          {}
      
          reference operator[](size_type n)
          { return v_[n]; }
      
          const_reference operator[](size_type n) const
          { return v_[n]; }
      
          size_type first_size() const
          { return v_.size(); }
      
          size_type second_size() const
          { return v_.empty() ? 0 : v_[0].size(); }
      
          // TODO: replicate std::vector interface if needed, like
          //iterator begin();
          //iterator end();
      
      private:
          type v_;
      
      };
      
      // for convenient printing only
      template <typename T> 
      ostream& operator<<(ostream& os, vecvec<T> const& v)
      {
          typedef vecvec<T> v_t;
          typedef typename v_t::value_type vv_t;
          for (typename v_t::size_type i = 0; i < v.first_size(); ++i)
          {
              for (typename vv_t::size_type j = 0; j < v.second_size(); ++j)
              {
                  os << v[i][j] << '\t';
              }
              os << endl;
          }
          return os;
      }
      
      int main()
      {
          vecvec<int> v(2, 3);
          cout << v.first_size() << " x " << v.second_size() << endl;
          cout << v << endl;
      
          v[0][0] = 1; v[0][1] = 3; v[0][2] = 5;
          v[1][0] = 2; v[1][1] = 4; v[1][2] = 6;
          cout << v << endl;
      }
      

      它只是一个模拟矩阵的非常简单的容器(只要用户承诺,通过改进 vecvec 定义或通过正确使用,矩形形状)。

      【讨论】:

      • 不幸的是,矩阵不能模拟问题。数据不是“矩形”,不同的行有不同的长度。
      • @Steve Jessop - 通常,在使用向量向量时,是的,由于 push_back 等的暴露,存在这种可能性,但它应该是一个插图,一个原始的解决方案,我留下了改进对读者来说,即保证行的共同大小保持不变,而不是暴露可能修改行向量维度等的操作。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-04-21
      • 2013-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-16
      • 1970-01-01
      相关资源
      最近更新 更多