I have this simple function template that's supposed to take a container as its template argument and print the contents:
template <typename T>
void print(typename T::iterator &it1,typename T::iterator &it2)
{
while (it1 != it2) {
std::cout<<*it1<<" ";
++it1;
}
}
I'm passing an iterator range (tipically the first and the off-the-end iterators) and I added the typename keyword to the function parameters because the compiler needs to know that I'm talking about a type and not a static member.
but when I pass a vector to the function the compiler says it can't find any match for the call (the closest match being the function itself) How can it be?
vector<double> dvec;
vector<double>::iterator it_b=dvec.begin();
vector<double>::iterator it_e=dvec.end();
print_it2(it_b,it_e);
the compiler says :
template argument deduction/substitution failed
could not deduce template parameter T
typename T::iterator
is a non-deduced context. The compiler has no way of knowing which T
should be deduced because it doesn't understand the semantic connection between the type member iterator
and a given T
. It would need to search through all types to find a match and be able to somehow disambiguate collisions. This is unreasonable, so the standard doesn't allow it.
You could supply the type explicitly:
print<vector<double>>(it_b, it_e);
print<decltype(dvec)>(it_b, it_e); //c++11
But it would probably be easier to forget about the container from which the iterator came and let the compiler deduce the iterator type:
template <typename It>
void print (It& it1, It& it2);
Maybe you have a reason to pass the iterators by reference, but it seems like you should pass by value instead:
template <typename It>
void print (It it1, It it2);