2012-03-08 12 views
11

質問のように、私はその理由が不思議です。 constと非constイテレータの間の距離を取得しようとすると、エラーが発生するためです。constとnonconstイテレータの組み合わせでstd :: distanceが機能しないのはなぜですか?

vector<int> v; 
auto it=v.begin(); 
auto cit=v.cbegin(); 
distance(it,cit); 


no matching function for call to ‘distance(__gnu_cxx::__normal_iterator<int*, std::vector<int> >&, __gnu_cxx::__normal_iterator<const int*, std::vector<int> >&) 

私のイテレータの理解が限られているので、私はそれがうまくいかない理由はありません。

答えて

19

std::distanceへの呼び出しで、反復子と定数の反復子が変更されているため、テンプレート引数の減算に失敗しています。これを修正するには、テンプレート引数を明示的に指定します。

std::vector<int> v; 
auto i1 = v.begin(); 
auto i2 = v.cbegin(); 

auto dist = std::distance<std::vector<int>::const_iterator>(i1, i2); 
6

std::distance()が唯一のテンプレートパラメータがかかるためです。

template <class InputIterator> 
iterator_traits<InputIterator>::difference_type 
distance(InputIterator first, InputIterator last); 

したがって、firstlastは同じ型に変換可能でなければならない、とテンプレートの解像度は、残念ながらvector<int>::iteratorvector<int>::const_iteratorに変換されることを考慮しています。

+0

なぜ2つのテンプレートパラメータでテンプレートを作成するだけでいいですか?それはcppコアランでそれを行うことは可能ですか?私は何を求めているのは、設計上の決定かラングの制限ですか? – NoSenseEtAl

+0

は明らかですが、2つのテンプレートパラメータでテンプレートを作ることができますが、1つのテンプレートparamバージョン – NoSenseEtAl

+0

@NoSenseEtAlと矛盾しているのでしょうか?この方法は簡単ですし、さまざまな種類のイテレータ間の距離を計算すること(たとえば、ランダムアクセス反復子と前方反復子)は、おそらく非常に頻繁にやりたいことではありません。実際には、2つのテンプレート引数を持つバージョンを書くことができますが、現実世界の問題はどのように解決されますか? –

3

std::distance動作していないものを、これらの2回の反復子で動作するテンプレート引数推論です。コンパイラは、最初のテンプレート引数の代わりにどの型を解決しようとしていますが、2つの潜在的な候補があります。

あなたはどちらか、の2つのうちの1つを行うのと同じタイプの唯一のイテレータを比較したり、テンプレートにタイプを提供することができます。

std::distance<std::vector<int>::const_iterator>(v.begin(), v.cbegin()); 
4

誰もが言うように、std::distanceは一つだけイテレータ型を取りますので、それはだ、とテンプレート引数の差し引きでは、どちらかを選択することはできません(iteratorconst_iteratorに変換され、後ろには変換されないので、どちらか一方のみ可能です)。

それは、このようなテンプレートに何か書く価値があるかもしれません:

std::distance(constify(v, it), cit); 

の代わりに、その偉大なロングタイプを書き出す:次に、あなたは、このようなテンプレートの控除を強制することができ

template <typename Container> 
typename Container::const_iterator constify(const Container &, typename Container::iterator it) { 
    return it; 
} 

を。 AFAIK Containerは、イテレータの引数だけから推論することができないため、Container&パラメータは残念です。

関連する問題