0

テンプレートクラスがありtemplate<typename T, typename R>ます。Rはタイプvector<T*>またはlist<T*>です。

クラスに演算子をオーバーロードさせたい[]ので、ベクトルの場合は組み込みの[]演算子を使用して効率を高め、リストの場合はイテレータを使用して実装します。

私にはテンプレートの特殊化の仕事のように聞こえるので、次のように書くことを考えました。

template<typename T, typename R>
T& tContainer_t<T, R>::operator[]( unsigned i )
{
    //TODO with iterators   
}

template<>
T& tContainer_t::operator[]<T, std::vector<T*> >( unsigned i )
{
    // TODO with built in [] operator
}

これは間違っており、コンパイラはこれを許可していません。

それを機能させる方法はありますか、それともtypeid()実行時に2つのオブジェクトを区別し、それに応じて動作するために使用する必要がありますか?

4

2 に答える 2

3

テンプレートを使用してこれを行う方法は、部分的に特殊化できるクラスで静的ヘルパー関数を作成することです。しかし、私がすることは次のとおりです。

template<typename T, typename R>
T& tContainer_t<T, R>::operator[]( unsigned i )
{
    //assuming that the container refernce is name container;
    typename R::iterator itr = container.begin();
    std::advance(itr, i);
    return *itr;
}

std::advanceランダムアクセスイテレータ(ベクトルなど)を備えたコンテナの場合、定数時間(基本的に、イテレータ+ nを実行)であり、ポインタルックアップベクトルを実行するのと同じくらい高速であることが保証されます。それ以外の場合はiterator++n回実行され、線形時間になります。constバージョンはconst_iteratorを使用しますが、基本的に同じです。

このようにすると、コードを変更することなく、さまざまなタイプのコンテナー(ベクターやリストだけでなく)を適切に処理できるようになります。

于 2012-05-23T11:48:27.220 に答える
2

演算子をオーバーロードする必要はありません。ライブラリaleadyには、役立つオーバーロードされた関数が含まれています。ランダムアクセスイテレータstd::advanceを利用して、イテレータを移動します。operator+()

template<typename T, typename R>
T& tContainer_t<T, R>::operator[]( unsigned i )     
{
    typename R::iterator it = myContainer.begin();
    std::advance(it, i);

    return *it;
} 
于 2012-05-23T11:48:51.643 に答える