Reputation:
Consider the following code:
#include <vector>
template <typename T>
using v_itt = typename std::vector<T>::iterator;
template <typename T>
void foo(v_itt<T>){ }
int main() {
typename std::vector<long>::iterator i = std::vector<long>().begin();
foo(i); //candidate template ignored: couldn't infer template argument 'T'
}
What's wrong with the code? I thought the T
should have been deduced to long
. Is there a way to fix that somehow?
Upvotes: 9
Views: 133
Reputation: 12757
I'd like just to add a possible workaround 3 to Marco's answer:
#include <vector>
template<typename T>
void real_foo( typename std::vector<T>::iterator){}
template <typename T>
void foo(T i){ real_foo<typename decltype(i)::value_type>(i); }
int main() {
std::vector<long> v;
foo(v.begin());
}
Upvotes: 4
Reputation: 43662
typename std::vector<T>::iterator
iterator
(a dependent type) it is not deducible in your code since it is in a nested name specifier and the standard says
§14.8.2.5/4
In certain contexts, however, the value does not participate in type deduction, but instead uses the values of template arguments that were either deduced elsewhere or explicitly specified. If a template parameter is used only in non-deduced contexts and is not explicitly specified, template argument deduction fails.
and §14.8.2.5/5
The non-deduced contexts are:
— The nested-name-specifier of a type that was specified using a qualified-id.
so this is a non-deduced context.
Possible workarounds:
Upvotes: 5