Почему этот шаблон не работает

Этот код не будет компилироваться с 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(),

2

Решение

Вы пытаетесь вывести аргумент шаблона из не выведенного контекста, § [temp.deduct.type] / 5

Неведуемые контексты:

— Спецификатор вложенного имени типа, указанного с помощью квалифицированного идентификатора.

то есть

template<typename T>
T getItem(typename std::forward_list<T>::const_iterator it)
^^^^^^^^^^^^^^^^^^^^

а также § [temp.deduct.type] / 4

Однако в определенных контекстах значение не участвует в выводе типа, а вместо этого использует значения аргументов шаблона, которые были либо выведены в другом месте, либо явно указаны. Если параметр шаблона используется только в не выведенных контекстах и ​​не указан явно, вывод аргумента шаблона завершается неудачно.

Если вы попытаетесь создать экземпляр foo это даст ту же ошибку. Вы не получаете ошибки для foo с кодом выше, так как зависимые имена ищутся только при создании экземпляра (это обычно упоминается как двухфазный поиск). ЧФР. Семантическая корректность неинстанцированных шаблонных функций C ++

8

Другие решения