2

Why do I get the compile error no matching function for call to `f( __gnu_cxx::__normal_iterator > >)'?

#include <vector>

template<typename T>
void f(const typename std::vector<T>::iterator &) {}

void g() {
  std::vector<int> v;
  f<int>(v.end());  // Compiles.
  f(v.end());  // Doesn't compile, gcc 4.3 can't find any match.
}

Ultimately I want to write a function which takes only a vector iterator, and fails to compile (with a meaningful error) for anything else. So template<typename T>void f(const T&) {} is not a good solution, because it compiles for other types as well.

pts
  • 80,836
  • 20
  • 110
  • 183
  • What's wrong with what you have? The reason for the compile error is that you're not providing a type to the templated function call. Even though you've provided `int` as the vector type, you still need to specify it for the call to `f`. – Chris Aug 18 '13 at 17:14
  • 2
    possible duplicate of [C++, template argument can not be deduced](http://stackoverflow.com/questions/6060824/c-template-argument-can-not-be-deduced) – user541686 Aug 18 '13 at 17:23

2 Answers2

4

You cannot deduce a template argument from a nested type. Think of, e.g., std::vector<T>::size_type which is always std::size_t: how would the compiler resolve the ambiguity? I realize that's not quite the case in your example but the same principle applies. For example, the iterator type of std::vector<T> can be T* which can also be the iterator type of std::array<T, N>.

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
3

G++ 4.8 gives a more complete message: http://ideone.com/ekN3xs

note:   template argument deduction/substitution failed:
note:   couldn't deduce template parameter ‘T’

f doesn't directly takes a T (like in "const T&") or a type where T is clear (like in "const std::vector<T>&") but a nested dependent type (here std::vector<T>::iterator) so the template type T cannot be automatically deduced from the argument.

Edit: Dietmar Kühl's answer gives a good rationale example.


For your "Ultimately" part, check How to check whether a type is std::vector::iterator at compile time? (the accepted answer uses some C++11 types, but you can use C++03 equivalents, e.g. from Boost)

Community
  • 1
  • 1
gx_
  • 4,690
  • 24
  • 31
  • See also the video http://channel9.msdn.com/Series/C9-Lectures-Stephan-T-Lavavej-Core-C-/Stephan-T-Lavavej-Core-C-2-of-n#time=37m30s (from about 37:30 to 42:00) – gx_ Aug 30 '13 at 19:20