This code won't compile with clang++ 6.0 or g++4.9.1 (Code has no meaning but this is the minimum example that makes it happen):
#include <forward_list>
template<typename T>
T getItem(typename std::forward_list<T>::const_iterator it) {
return *it;
}
template<typename T>
void foo() {
std::forward_list<T> list;
auto item = getItem(list.cbegin());
}
template<typename T>
void bar(const std::forward_list<T>& list) {
auto item = getItem(list.cbegin());
}
int main() {
std::forward_list<int> list;
bar(list);
}
I get this error
t2.cpp:17:17: error: no matching function for call to 'getItem'
auto item = getItem(list.cbegin());
^~~~~~~
t2.cpp:22:5: note: in instantiation of function template specialization 'bar<int>' requested here
bar(list);
^
t2.cpp:4:3: note: candidate template ignored: couldn't infer template argument 'T'
T getItem(typename std::forward_list<T>::const_iterator it) {
^
1 error generated.
To fix it I need to change bar()
's call like this:
template<typename T>
void bar(const std::forward_list<T>& list) {
auto item = getItem<T>(list.cbegin());
}
I don't understand why the compiler is not able to infer the template argument, and the strange thing is that the compiler is perfectly happy with foo()
.
You're trying to deduce a template argument from a non-deduced context, § [temp.deduct.type]/5
i.e.
and § [temp.deduct.type]/4
If you try to instantiate
foo
it will give the same error. You're not getting errors forfoo
with the code above since dependent names are only looked up at instantiation (this is commonly referred to as two-phase lookup). Cfr. Semantic correctness of non-instantiated C++ template functions