Я начал писать класс, который работал бы так же, как std::vector
, но с некоторыми математическими операциями. В основном такие вещи, как норма вектора и перегрузка важных математических операторов (+, - и т. Д.), Которые будут складывать, вычитать вещи поэлементно.
Класс размещен ниже, я использовал boost::operators
, чтобы написать все математические операторы, и все они работают без нареканий. Я столкнулся с некоторыми проблемами при реализации итератора. Я попытался написать итератор как вложенный класс и использовать boost::iterator
для получения большей / всей функциональности итератора std::vector
.
Здесь я столкнулся с проблемой: код не будет компилироваться с выводом ошибок, связанных с шаблоном, примерно на 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);
};