2011-04-13 68 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