5

したがって、基本的に私がやりたいことは、たとえば疑似コードで、具象型の任意のコレクションにイテレータを返す純粋仮想メソッドを用意することです。

virtual Iterator<T> getIterator() const = 0;

このクラスのユーザーは、実際には、子クラスがどの実装を使用するかを気にしません。セット、ベクトル、リスト、配列などです。

私はstd::iteratorクラスを認識していますが、単純なベクトルを操作するために正しく指定する方法が見つかりません。

virtual std::iterator<std::random_access_iterator_tag,T> getIterator() const = 0;

myVector.begin() // compilation error in implementation

型パラメーターとして定義std::iteratorしても機能しませんでした。const Tまた、そのままにしてT、代わりにポインターと参照型をconst T*andとして定義しようとしconst T&ました。

std::vector実装を見てみると、がstd::vector::const_iterator実際に派生元から_Iterator012派生していることがわかりました_Iterator_base

標準で任意のコレクションを操作する方法がないことは本当に私を悩ませています。のようにクラスをテンプレートとして実装すること<algorithm>は、次の 2 つの理由から、私にとっては選択肢ではありません。

  • 実際の値の型を制御できない
  • クラス テンプレートを作成して設計を複雑にし、柔軟性を低下させたくないだけです。

使用された型パラメーターTはデモ用であり、実際には具象型です。

4

2 に答える 2

5

これは、型消去を使用した基本的で非常に基本的なスケルトンアプローチです。ただし、不足している多くの詳細を入力する必要があります。

#include <memory>

template <typename T>
class TEIterator
{
    struct TEImplBase
    {
        virtual ~TEImplBase() { }
        virtual std::unique_ptr<TEImplBase> clone() const = 0;
        virtual void increment() = 0;
        virtual T & getValue() = 0;
        T * getPointer() { return std::addressof(getValue()); }
    };

    template <typename Iter>
    struct TEImpl
    {
        Iter iter;

        TEImpl(Iter i) : iter(i) { }

        virtual T & getValue()
        { return *iter; }

        virtual std::unique_ptr<TEImplBase> clone() const
        { return std::unique_ptr<TEImplBase>(new TEImpl<Iter>(*this)); }

        virtual void increment()
        { ++iter; }
    };

    std::unique_ptr<TEImplBase> impl;

public:

    template <typename T>
    TEClass(T && x)
    : impl(new TEImpl<typename std::decay<T>::type>(std::forward<T>(x)))
    {
    }

    TEClass(TEClass && rhs) = default;

    TEClass(TEClass const & rhs) : impl(rhs.impl.clone()) { }

    TEIterator & operator++()
    {
        impl->increment();
        return *this;
    }

    T & operator*() { return impl->getValue(); }
    T * operator->() { return impl->getPointer(); }
};

使用法:

std::vector<int> v;
std::deque<int> dq;

TEIterator<int> a = v.begin(), b = dq.end();
于 2012-12-02T15:51:55.577 に答える
0

仮想メソッドを使用する場合、任意の戻り値は使用できません。できることは、イテレータのラッパーである基本クラスと、そのラッパー クラスのサブクラスを定義することです。

ただし、その場合でも、C++ 標準ライブラリにはいくつかの反復子クラスがあるため、最小公分母に制限する必要があります。

したがって、AFAICS、任意のイテレータを使用するこのようなメソッドは、テンプレートを使用しないと実際には実現できません。

于 2012-12-02T15:46:20.033 に答える