1

次の機能を持つ stl のようなコンテナー クラスを作成しています。

    Iterator begin(){
        return Iterator(data_.begin(), 1);
    }

    ConstIterator begin() const{
        return ConstIterator(data_.begin(), 1);
    }

両方を置き換える1つの関数を作成できると思います:

    template <typename itr0, typename itr1>
    itr0 begin(){
        return itr1(data_.begin(), 1);
    }

以下を呼び出すと、コンパイル時にコードが生成されます。

    Iterator it = foo.begin<Iterator, Iterator>();
    ConstIterator it = foo.begin<ConstIterator const?, ConstIterator>();

私の最初の質問は、実際には typename は何ConstIterator begin() constですか?

第二に、このメタプログラミングがクラスの外部から透過的になるようにする方法はありますか? つまり、標準的な方法で記述されているかのように、次のコードを使用して begin() を呼び出すことはできますか?

    C foo;
    const C foo2;
    Iterator it = foo.begin();
    ConstIterator it = foo2.begin();
4

1 に答える 1

1

残念ながら、2つのメソッドを別々に定義する必要があります。これは、すでに述べたように、それらのシグネチャはconst修飾子によって異なるためです。それを克服できるテンプレートウィザードはありません(少なくとも私が知っているものはありません)。

ただし、さまざまな手法を使用して、それらの実装を1つのメソッドに組み合わせることができます。const_castこれは、 'ingの必要性を回避するそのようなオプションの1つです。

struct Container
{
    template< typename I, typename C >
    friend I begin_impl( C & c ){
      return I( c.data_.begin(), 1 );
    }

    Iterator begin(){
        return begin_impl< Iterator >( *this ); // *this is "Container"
    }

    ConstIterator begin() const{
        return begin_impl< ConstIterator >( *this ); // *this is "Container const"
    }
};

その他のオプションについては、こちらをご覧ください。

于 2012-04-25T01:58:39.167 に答える