2011-04-13 72 views
2

我開始寫一個類,其行爲非常像std::vector,但有一些數學操作。主要是像向量的規範和超載重要的數學運算符(+, - 等),這將增加元素明智地減去元素。通過構圖的數學矢量課

這個課程在下面發佈,我用boost::operators來編寫所有的數學運算符,它們都完美無缺地工作。在實現迭代器時遇到了一些問題。我試圖將迭代器編寫爲嵌套類,並使用boost::iterator來獲取迭代器的大部分/全部功能。

這是我遇到麻煩的地方,代碼不會編譯大約2英里的模板相關錯誤輸出。如果您有興趣,我可以發帖,但是是典型的詳細提升模板錯誤。

我的問題是雙重的。

首先是構圖的最佳設計選擇?我可以用私有繼承或裝飾器模式做得更好嗎?或者,也許有人知道在圖書館實施這個想法?

其次,我在做什麼錯誤的迭代器?我感覺好像在我的boost::iterator實現中缺少一些基本的東西,並且想要修復它而不是改變我的設計。

我沒有在大多數方法中包含實現,因爲它們不是微不足道就是不重要。

//publicly inherits important boost::operators classes 
template <class T> 
class Coords: boost::arithmetic<Coords<T> 
      ,boost::arithmetic<Coords<T>, T 
//    ,boost::indexable<Coords<T>,int,T& 
//    ,boost::dereferenceable<Coords<T>, T*> 
//   > 
    > 
> 
{ 
private: 
    //private member 
    std::vector<T> x_; 
public: 

    //public constructors 
    Coords(int n, T x): x_(n,x){}; 
    Coords(int n): x_(n){}; 
    Coords(std::vector<T> &x); 
    Coords(const Coords &rhs); 

    //iterator nested class, public inherits boost::iterator_facade 
    class iterator: public boost::iterator_facade<iterator, Coords<T>, std::random_access_iterator_tag>{ 
     private: 
      typename std::vector<T>::iterator iter_; 

      friend class boost::iterator_core_access; 

      void increment() { iter_ = iter_++;}; 

      void decrement() { iter_ = iter_--;}; 

      void advance(int n){ iter_ = iter_+=n;}; 

      void equal(iterator const &other) const{ 
       return this->iter_ == other.iter_; 
      } 

      T& dereference() const {return *iter_;}; 

      int distance_to(iterator const &other) const{ 
       return this->iter_ - other.iter_; 
      } 

     public: 
      iterator():iter_(0){}; 

      explicit iterator(const typename Coords<T>::iterator& it):iter_(it.iter_){}; 

      explicit iterator(const typename std::vector<T>::iterator& it):iter_(it){}; 

    }; 

    //methods from std::vector I would like to 'copy' 
    typename Coords<T>::iterator begin(){return iterator(x_.begin());}; 
    typename Coords<T>::iterator end(){return iterator(x_.end());}; 
    typename Coords<T>::iterator operator[](std::size_t n); 
    std::size_t size(){return x.size()}; 

    //mathematical methods 
    T norm() const; 
    T square() const; 
    T sum() const; 
    T dotProd(const Coords &rhs); 

    //important operator overloads 
    Coords operator+=(const T &rhs); 
    Coords operator-=(const T &rhs); 
    Coords operator*=(const T &rhs); 
    Coords operator/=(const T &rhs); 
    Coords operator+=(const Coords<T> &rhs); 
    Coords operator-=(const Coords<T> &rhs); 
    Coords operator*=(const Coords<T> &rhs); 
    Coords operator/=(const Coords<T> &rhs); 
}; 
+0

我假設你正在建造這個班作爲個人練習。如果您想實際使用數學庫,請嘗試[Blitz ++](http://www.oonumerics.org/blitz/)。 – chrisaycock 2011-04-13 18:15:54

+0

@chris閃電戰已經很久了。它的ublas或特徵或犰狳。 – Anycorn 2011-04-13 18:43:34

+0

@Anycorn是的,我剛剛意識到他們已經很久沒有更新過了。萬歲uBlas! – chrisaycock 2011-04-13 18:49:39

回答

1

這修正了一些與程序問題:

#include <boost/operators.hpp> 
#include <boost/iterator.hpp> 
#include <boost/iterator/iterator_facade.hpp> 
#include <vector> 
//publicly inherits important boost::operators classes 
template <class T> 
class Coords: boost::arithmetic<Coords<T> 
      ,boost::arithmetic<Coords<T>, T 
//    ,boost::indexable<Coords<T>,int,T& 
//    ,boost::dereferenceable<Coords<T>, T*> 
//   > 
    > 
> 
{ 
private: 
    //private member 
    std::vector<T> x_; 
public: 

    //public constructors 
    Coords(int n, T x): x_(n,x){}; 
    Coords(int n): x_(n){}; 
    Coords(std::vector<T> &x); 
    Coords(const Coords &rhs); 

    //iterator nested class, public inherits boost::iterator_facade 
    class iterator: public boost::iterator_facade<iterator, T, boost::random_access_traversal_tag >{ 
     private: 
      typename std::vector<T>::iterator iter_; 

      friend class boost::iterator_core_access; 

      void increment() { ++iter_;} 

      void decrement() { --iter_; } 

      void advance(int n){ iter_+=n;}; 

      bool equal(iterator const &other) const{ 
       return this->iter_ == other.iter_; 
      } 

      T& dereference() const {return *iter_;}; 

      int distance_to(iterator const &other) const{ 
       return this->iter_ - other.iter_; 
      } 

     public: 
      iterator():iter_(0){}; 

      iterator(const iterator& it):iter_(it.iter_){}; 
      iterator(iterator& it):iter_(it.iter_){}; 

      explicit iterator(const typename std::vector<T>::iterator& it):iter_(it){}; 

    }; 

    //methods from std::vector I would like to 'copy' 
    iterator begin(){return iterator(x_.begin());}; 
    iterator end(){return iterator(x_.end());}; 
    iterator operator[](std::size_t n); 
    std::size_t size(){return x_.size();}; 

    //mathematical methods 
    T norm() const; 
    T square() const; 
    T sum() const; 
    T dotProd(const Coords &rhs); 

    //important operator overloads 
    Coords operator+=(const T &rhs); 
    Coords operator-=(const T &rhs); 
    Coords operator*=(const T &rhs); 
    Coords operator/=(const T &rhs); 
    Coords operator+=(const Coords<T> &rhs); 
    Coords operator-=(const Coords<T> &rhs); 
    Coords operator*=(const Coords<T> &rhs); 
    Coords operator/=(const Coords<T> &rhs); 
}; 

int main() { 
    Coords<int> c(3); 
    for(Coords<int>::iterator it(c.begin()); it != c.end(); ++it) 
    *it; 
} 
  • Boost documentation似乎是說,第三個模板參數iterator_facadeboost::標籤,而不是一個std::標籤。
  • iterator_facade的第二個模板參數是值類型,而不是容器類型。
  • 代碼爲increment,decrementadvance全部產生(I 認爲)未定義的行爲。
  • 從類定義中引用類成員時,不需要列出類名。有幾個地方需要刪除Coords<T>::
+0

我同意你的第一點,但我無法在任何地方找到boost ::'標記。在寫增量,遞減,提前時,我實在不知道我在想什麼。一定是低咖啡。與我原來的代碼,我不明白的主要問題是1)第二個模板參數和複製構造函數顯式。其他問題很直接。非常感謝! – rymurr 2011-04-14 08:13:31