2

私は、数学的なstd::vector操作を使って、同じように動作するクラスを書き始めました。主に、ベクトルのノルムや、要素ごとに物事を加算、減算する重要な数学演算子(+、-など)のオーバーロードなどがあります。

クラスは以下に掲載されています。私はboost::operatorsすべての数学演算子を作成するために使用しましたが、それらはすべて問題なく機能します。イテレータを実装するときにいくつかの問題が発生しました。イテレータをネストされたクラスとして記述し、イテレータのboost::iteratorほとんど/すべての機能を取得するために使用しようとしましたstd::vector

これは私が問題に遭遇した場所です。コードは約2マイル相当のテンプレート関連のエラー出力でコンパイルされません。興味があれば投稿できますが、典型的な冗長ブーストテンプレートエラーです。

私の質問は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);
};
4

1 に答える 1

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のドキュメントには、 の 3 番目のテンプレート パラメータiterator_facadeboost::タグではなくタグであると書かれているようstd::です。
  • の 2 番目のテンプレート パラメーターiterator_facadeは、コンテナーの型ではなく、値の型です。
  • incrementdecrement、およびadvanceすべてのコードは(私が思うに) 未定義の動作を生成しました。
  • クラス定義内からクラス メンバーを参照する場合、クラス名を列挙する必要はありません。Coords<T>::削除しなければならない場所がいくつかありました。
于 2011-04-13T19:08:55.110 に答える