c++ - 为什么这个模板推理失败

标签 c++ templates c++11 template-argument-deduction

此代码无法使用 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/

相关文章:

c++ - 为什么在 C++11 中允许通过 const_iterator 进行删除?

c++ - 自动扣除失败并显示消息 "inconsistent deduction for auto return type"

c++ - 无用(也许是错误的?)gcc 错误消息

c++ - 如何在 C++ 中为 Windows 的 GDI 正确设置库?

c++ - 如何判断 C++ 生成了什么模板

c++ - 在特定情况下使用 C++ 模板将整数映射到类型失败

C++11 constexpr 过时的模板元编程?

c++ - 如何使用WINAPI (C++) 执行 sleep 状态S1

c++ - 重复使用可变参数函数参数不起作用

c++ - 具有X类,如何将X作为模板参数传递给自身?