Common vector of vectors in C ++

Is there a good way in C ++ to implement (or fake) a type for a common vector of vectors?

Ignore the problem when a vector of vectors is a good idea (unless there is something equivalent, which is always better). Suppose that he accurately models the problem and that the matrix does not accurately model the problem. Suppose also that template functions that take these parameters as parameters need to be controlled by the structure (for example, by calling push_back), so they cannot just take on a common type that supports [][] .

What I want to do:

 template<typename T> typedef vector< vector<T> > vecvec; vecvec<int> intSequences; vecvec<string> stringSequences; 

but of course this is not possible, since typedef cannot be programmed.

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

is close and will preserve type duplication in every templated function that works with vecvecs, but will not be popular with most C ++ programmers.

+48
c ++ stl
Nov 16 '08 at 15:26
source share
4 answers

You want to have a template typedef. This is not yet supported in current C ++. The workaround is

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

In the following C ++ (called C ++ 0x, C ++ 1x due to 2010) this would be possible:

 template<typename T> using vecvec = std::vector< std::vector<T> >; 
+51
Nov 16 '08 at 15:31
source share

I am using Boost.MultiArray , which is implemented in the boost library.

NTN

+5
Nov 18 '08 at 10:47
source share

You can simply create a new template:

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

If you do this, you must remember that the vector destructor is not virtual and does not do something like this:

 void test() { std::vector< std::vector<int> >* pvv = new vecvec<int>; delete pvv; } 
+4
Nov 17 '08 at 22:39
source share

You can implement a basic vector vector using std::vector as the basis:

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

It is just a very simple container that simulates a matrix (as long as the user promises, by improving the definition of vecvec or by using it correctly, in a rectangular shape).

+2
Feb 06 '10 at 0:24
source share



All Articles