为什么迭代器类型推导失败?

时间:2013-03-04 18:38:02

标签: c++ templates typedef type-deduction

为什么这在C ++中不起作用?
为什么我不能像这样将foo的参数限制为std::vector<T>::iterator,最佳解决方法是什么?

#include <vector>

template<class T>
void foo(typename std::vector<T>::iterator) { }

int main()
{
    std::vector<int> v;
    foo(v.end());
}

错误是:

In function ‘int main()’:
     error: no matching function for call to ‘foo(std::vector<int>::iterator)’
     note: candidate is:
    note: template<class T> void foo(typename std::vector<T>::iterator)
    note:   template argument deduction/substitution failed:
     note:   couldn’t deduce template parameter ‘T’

2 个答案:

答案 0 :(得分:6)

它不起作用的主要原因是因为sandard说的那样 此处的T位于非推导的上下文中。之所以如此 上下文不推断是因为当你传递一些类型的时候 函数,编译器必须实例化每一个 可能的std::vector(包括此类型中没有的类型) 特别翻译单位)为了试图找到一个 有相应的类型。

当然,在std::vector的情况下,编译器可以包含 自从类的语义以来,使这项工作变得有些神奇 由标准定义。但一般来说, TemplateClass<T>::NestedType可以是字面上的typedef 任何东西,编译器都无法做到这一点。

答案 1 :(得分:2)

简单。

struct X {};
template<> class std::vector<X> {
    typedef std::vector<int>::iterator iterator;
};

糟糕。

模板是Turing-Complete。您要求编译器从结果中推断出参数。在一般情况下这是不可能的,甚至忽略了非一对一对应的可能性。

通常,您将迭代器类型本身作为模板参数。这允许其他随机访问迭代器,如deque,循环缓冲区等。