2
#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

max66
  • 65,235
  • 10
  • 71
  • 111
SergeantPenguin
  • 843
  • 7
  • 16

0 Answers0