了解模板参数推导

9 c++ templates

请考虑以下代码:

#include <vector>

template <typename T>
using v_itt = typename std::vector<T>::iterator;

template <typename T>
void foo(v_itt<T>){ }

int main() {
    typename std::vector<long>::iterator i = std::vector<long>().begin();
    foo(i); //candidate template ignored: couldn't infer template argument 'T'
}
Run Code Online (Sandbox Code Playgroud)

DEMO

代码有什么问题?我认为T应该推断出来long.有办法以某种方式解决这个问题吗?

Mar*_* A. 5

typename std::vector<T>::iterator
Run Code Online (Sandbox Code Playgroud)

iterator(一个依赖类型)它在你的代码中是不可推导的,因为它是一个嵌套的名称说明符,标准说

§14.8.2.5/ 4

但是,在某些上下文中,该值不参与类型推导,而是使用模板参数的值,这些参数可以在别处推导或明确指定.如果模板参数仅在非推导的上下文中使用且未明确指定,则模板参数推断将失败.

和§14.8.2.5/ 5

未推断的上下文是:

- 使用qualified-id指定的类型的嵌套名称说明符.

所以这是一个非演绎的背景.

可能的解决方法:

  1. 传递向量引用而不是迭代器
  2. 使用标记调度和编译时断言来验证迭代器