此代码无法使用 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()
非常满意。
最佳答案
您正在尝试从非推导上下文推导模板参数,§ [temp.deduct.type]/5
The non-deduced contexts are:
— The nested-name-specifier of a type that was specified using a qualified-id.
即
template<typename T>
T getItem(typename std::forward_list<T>::const_iterator it)
^^^^^^^^^^^^^^^^^^^^
和§ [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.
如果您尝试实例化foo
it will give the same error .使用上面的代码,您不会收到 foo
的错误,因为从属名称仅在实例化时查找(这通常称为两阶段查找)。 CFR。 Semantic correctness of non-instantiated C++ template functions
关于c++ - 为什么这个模板推理失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26842738/