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
The non-deduced contexts are:
— The nested-name-specifier of a type that was specified using a qualified-id.
i.e.
template<typename T>
T getItem(typename std::forward_list<T>::const_iterator it)
^^^^^^^^^^^^^^^^^^^^
and § [temp.deduct.type]/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.
If you try to instantiate foo it will give the same error. You're not getting errors for foo 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With