代码之家  ›  专栏  ›  技术社区  ›  Steve Jessop

C++中向量的通用向量

  •  48
  • Steve Jessop  · 技术社区  · 16 年前

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

    我想做的是:

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

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

    是关闭的,并且可以避免在VECVECS上运行的每个模板函数上重复该类型,但不会与大多数C++程序员流行。

    4 回复  |  直到 16 年前
        1
  •  51
  •   Johannes Schaub - litb    16 年前

    您需要模板typedef。就是

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

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

    template<typename T>
    using vecvec = std::vector< std::vector<T> >;
    
        2
  •  5
  •   mloskot    15 年前
        3
  •  4
  •   Rexxar    16 年前

    您只需创建一个新模板:

    #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;
    }
    
        4
  •  2
  •   mloskot    15 年前

    可以使用实现向量类型的基本向量 std::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;
    }