2017-01-13 13 views
4

私はちょっと休憩してからC++に戻ってきました。ここでは、タプルのコンテナを検索し、タプルのN番目の要素が条件(値または単項関数)を満たしていれば、イテレータを返す関数について考えました。Tuple find関数の引数の置換に失敗しました

だから、ここで私は今で書かれたものである。なぜなら

私は奇妙な見つける
error: no matching function for call to 
'find(std::vector<std::tuple<int, float, bool> >::iterator, std::vector<std::tuple<int, float, bool> >::iterator, int)' 
note: couldn't deduce template parameter 'template<class ...> class Container' 
    auto iter = find<0>(vec.begin(), vec.end(), 1); 
                  ^

template<std::size_t tupleIndex, 
     template<typename...> class Container, 
     template<typename...> class Tuple, 
     typename... TupleArgs> 
auto find(typename Container<Tuple<TupleArgs...>>::iterator it1, 
      typename Container<Tuple<TupleArgs...>>::iterator it2, 
      decltype(std::get<tupleIndex>(std::declval<Tuple<TupleArgs...>>())) searchedValue) { 
    for(; it1 != it2; ++it1) { 
     if(std::get<tupleIndex>(*it1) == searchedValue) 
      break; 
    } 
    return it1; 
} 

をしかし、それは呼び出しに失敗します。

using Tuple = std::tuple<int, float, bool>; 
std::vector<Tuple> vec{std::make_tuple(1, 1.5, false), 
         std::make_tuple(2, 2.5, true), 
         std::make_tuple(3, 3.5, false)}; 

auto iter = find<0>(vec.begin(), vec.end(), 1); //error 

エラーそれは候補者の署名に完全に合う:

find(typename Container<Tuple<TupleArgs ...> >::iterator, typename Container<Tuple<TupleArgs ...> >::iterator, decltype (std::get<tupleIndex>(std::declval<Tuple<TupleArgs ...> >())) 

なぜこの場合、Containerを推論できないのですか?イテレータをテンプレート化するだけで済ませることができますが、この場合は具体的にしたいと思います。

+1

私は質問をdownvoteする理由はありません、downvoter説明してくださいできますか? – SergeyA

答えて

4

typename Container<Tuple<TupleArgs...>>::iteratorは、non-deduced contextです。コンパイラは、イテレータがどのコンテナから来ているのかを調べることはできません。なぜなら、必ずしもこの2つの間に1対1のマッピングがあるわけではないからです。

あなたがお勧めするように、最良の選択肢は、正しく推定できるように、イテレータタイプをテンプレートパラメータとして持つことです。

+1

私の仲間のプログラマの一人のように、「コンパイラは型の方程式を解くことはできません」と言われています。 – SergeyA

関連する問題