#include <vector>
#include <iostream>
template <unsigned X> class A{};
template <unsigned X> void testfunc(std::vector<A<X>> f) { std::cout << "Hello one" << std::endl;}
template <unsigned X> void testfunctwo(typename std::vector<A<X>>::iterator f) { std::cout << "Hello two" << std::endl;}
int main(){
std::vector<A<2>> f;
f.push_back(A<2>());
testfunc(f);
testfunctwo<2>(f.begin());
testfunctwo(f.begin());
}
You can see in the first case the compiler can deduce the value of X
as expected. In the second case the function takes a vector iterator an explicit template parameter is used, the function of course runs normally. In the third case there is template argument deduction failure:
error: no matching function for call to 'testfunctwo(std::vector<A<2u> >::iterator)'|
note: candidate: template<unsigned int X> void testfunctwo(typename std::vector<A<X> >::iterator)|
note: template argument deduction/substitution failed:|
note: couldn't deduce template parameter 'X'|
The compiler notes that the template function testfunctwo
is a candidate but cannot deduce the template parameter X
. The only difference between it and testfunc
is that it takes an iterator instead. How come the introduction of a typename causes template argument deduction to fail? f.begin()
has type std::vector<A<2>>::iterator
, personally looking at it, it should be very clear what the template parameter should be.
Compiler is MinGW g++ 6.1.0