2013-03-04 70 views
1

爲什麼這不適用於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

解決方法是當模板參數無法推斷時通常使用的解決方法,明確指出:'foo (v.end());' – 2013-03-04 18:50:34

回答

5

它不起作用的主要原因是因爲標準說 T這裏是在一個非推導的上下文中。之所以不推導上下文的原因是因爲當您將某種類型傳遞給 函數時,編譯器必須實例化每個可能的std::vector(包括對於此 特定翻譯單元中不存在的類型),以嘗試找到一個 有一個對應的類型。

當然,在std::vector情況下,編譯器可以包含 一些魔術,使這項工作,因爲類 的語義由標準定義。但通常, TemplateClass<T>::NestedType可以是任何類型的字面定義 ,並且編譯器無法對此做任何事情。

2

簡單。

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

糟糕。

模板是圖靈完成的。您正在要求編譯器從結果中推斷參數。在一般情況下這是不可能的,甚至忽略了非一一對應的可能性。

通常,您將迭代器類型本身作爲模板參數。這允許像deque,循環緩衝區等其他隨機訪問迭代器。