2011-10-28 20 views
3

を私はこのようなインタフェースを持つ機能を持つようにしたい:STLコンテナにイテレータのインデックスを検索する - 必要性のテンプレート関数

template<typename T, typename R> int find_index (const T& list, const R& value); 

私が知っているように、イテレータを返しSTLでfind()あります。イテレータのインデックスを返す必要があります(インデックスされていないコンテナ(std::listなど)の場合でも)。私はこのコードを試してみました:

template<typename T, typename R> 
int find_index (const T& list, const R& value) 
{ 
    int index = 0; 
    for (T::const_iterator it = list.begin(); it != list.end(); it++, index++) 
     if ((*it) == value) 
      return index; 
    return -1; 
} 

をしかし、コンパイラがit上のエラーを示して - テンプレート型名からconst_iteratorを取得するために許可されていないように思えます。私はそれを回ることができますか?

最悪の場合は、イテレータの開始と終了をfind_index引数に渡すことができますが、それほどうまくありません。エレガントなソリューションに感謝します。

答えて

11
for (typename T::const_iterator it = list.begin(); it != list.end(); ++it, ++index) 

は、問題を解決するはずです。

依存型(テンプレートパラメータに依存する型)を使用する場合、コンパイラは具体的な型のテンプレートをインスタンス化するまではconst_iteratorが型であることを知らず、静的な変数などでもかまいません。 typenameキーワードを使用して、const_iteratorが実際にタイプであることを彼に伝えます。

あなたも autoキーワード用いて全 typename問題を回避することができますC++ 11では

:あなたはすでに(おそらくいくつかの他の操作から)イテレータを持っている場合は、あなただけのこともでき

for (auto it = list.begin(); it != list.end(); ++it, ++index) 

をこれはあなたを使用して、std::listのための線形複雑度を持つため

#include <iterator> 

int index = std::distance(list.begin(), it); 

しかし:リストの反復子を始めるから距離を計算find_indexの機能は、std::findよりも優れたアイデアであり、それに続いてstd::distanceが少なくともパフォーマンス面では優れています。

関連する問題