为什么这在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’
答案 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,循环缓冲区等。