Этот код не будет компилироваться с clang++ 6.0 или g++ 4.9.1 (код не имеет значения, но это минимальный пример, который позволяет это сделать):
#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);
}
я получаю эту ошибку
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.
Чтобы исправить это, мне нужно изменить вызов bar()
следующим образом:
template<typename T>
void bar(const std::forward_list<T>& list) {
auto item = getItem<T>(list.cbegin());
}
Я не понимаю, почему компилятор не может вывести аргумент шаблона, и странно то, что компилятор вполне доволен foo()
.
template<typename T> auto getItem(T it) -> decltype(*it) { return *it; }
. Не очень хорошая идея, но работает )) - person borisbn   schedule 10.11.2014auto item = *list.begin();
? - person Casey   schedule 10.11.2014