4

This is a follow up to James' answer to this question: Flattening iterator

I try to change James' solution, so that it can handle template classes. Turns out I get stuck at the call to the function (there "flatten", here "foo"). It workd when I specialise for each template parameter, which would be possible, because there is only three (1,2,3) that will ever occur. The general case does not compile. See the code and the gcc's error message below.

#include <iterator>
#include <vector>

template <int I> 
class A{};

template <int I>
void foo( typename std::vector< A <I> >::iterator first ,
          typename std::vector< A <I> >::iterator last) {}

//void foo( typename std::vector< A <1> >::iterator first , 
//          typename std::vector< A <1> >::iterator last) {} // this works

int main()
{
  std::vector< A<1> > v;
  foo(v.begin(),v.end());
  return 0;
}

error message after compiling with gcc 4.6.3:

test_templ_func.cc: In function ‘int main()’:
test_templ_func.cc:15:24: error: no matching function for call to ‘foo(std::vector<A<1> >::iterator, std::vector<A<1> >::iterator)’
test_templ_func.cc:15:24: note: candidate is:
test_templ_func.cc:8:6: note: template<int I> void foo(typename std::vector<A<I> >::iterator, typename std::vector<A<I> >::iterator)
Community
  • 1
  • 1
steffen
  • 8,572
  • 11
  • 52
  • 90
  • 1
    Why have you defined same function template *twice*? In one, you forgot to use `typename`, otherwise everything else is same. – Nawaz Jul 11 '12 at 16:51
  • @Nawaz: Sorry, cut'n'paste error... thanks for poonting it out. corrected that. – steffen Jul 11 '12 at 17:01
  • 1
    The "usual" thing to do here is to declare `foo` as `template ForwardIterator foo(ForwardIterator first, ForwardIterator last);` and let the iterator type be deduced. Unless you really need the value of `I`. – James McNellis Jul 12 '12 at 04:29
  • @James: That is what was there in the first place and I changed it to supposedly fix it to work with a slightly different class. Turned out the problem was something different, changed it back now and it works! – steffen Jul 12 '12 at 08:11

2 Answers2

2

Those are dependent type parameters and compiler can't resolve them, eg: Template function with dependent type parameters within template class

You can have workaround by using http://en.cppreference.com/w/cpp/types/enable_if and using some type trait template.

Template decudection guidelines

Community
  • 1
  • 1
Anycorn
  • 50,217
  • 42
  • 167
  • 261
1

Template argument deduction works for a number of cases, but there are limits to what it can do. You've hit one of the limits.

Stephan Lavavej (who currently works on the STL for Microsoft) just did a nice little video about template argument deduction. While he doesn't talk about your example explicitly, he does cover a few similar situations and provides a nice overview of what template argument deduction can do.

Nate Kohl
  • 35,264
  • 10
  • 43
  • 55