2012-11-26 80 views
3

我被這個錯誤卡住了。 我也找到了解決方法,但它有種殺死鍛鍊的全部目的。錯誤C2783無法推斷模板參數

我想創建一個函數,將需要兩個迭代器指向相同的容器。我會找到它們之間的元素總和。我創建了順序容器的一般函數,就像vector一樣正常工作。我重載了關聯容器的相同函數。這是一個錯誤。

map<string,double> myMap; 
myMap["B"]=1.0; 
myMap["C"]=2.0; 
myMap["S"]=3.0; 
myMap["G"]=4.0; 
myMap["P"]=5.0; 

map<string,double>::const_iterator iter1=myMap.begin(); 
map<string,double>::const_iterator iter2=myMap.end(); 

cout<<"\nSum of map using the iterator specified range is: "<<Sum(iter1,iter2)<<"\n"; 
//Above line giving error. Intellisense is saying: Sum, Error: no instance of overloaded function "Sum" matches the argument list. 

//function to calculate the sum is listed below (It appears in a header file with <map> header included): 
template <typename T1,typename T2> 
double Sum(const typename std::map<T1,T2>::const_iterator& input_begin,const typename std::map<T1,T2>::const_iterator& input_end) 
{ 
double finalSum=0; 
typename std::map<T1,T2>::const_iterator iter=input_begin; 

for(iter; iter!=input_end; ++iter) 
{ 
    finalSum=finalSum+ (iter)->second; 
} 

return finalSum; 
} 

編譯錯誤是: 1> C:\ Documents和Settings \ ABC \我的文檔\ Visual Studio 2010的\項目\ demo.cpp(41):錯誤C2783:「雙總和(常量的std ::地圖::爲const_iterator &,常量的std ::地圖::爲const_iterator &)」:不能推導出模板參數爲 '

解決方法T1':

如果呼叫總和(iter1,iter2)被替換Sum < string,double>(iter1,iter2),它編譯得很好。

我是否試圖按照C++標準做一些不可能的事情?

+0

嘗試使Sum的模板類型成爲迭代器而不是迭代器的內容類型。 模板 \t 雙總和(常量T&input_begin,常量T&input_end) – Jason

+0

然後,它與一般的總和功能我已經爲載體,其他順序容器書面相撞。 – NotAgain

+0

然後專注你的通用和這裏的具體迭代器類型: – Jason

回答

6

錯誤其實是相當清晰的,在下面的模板:

template <typename T1,typename T2> 
double Sum(const typename std::map<T1,T2>::const_iterator& input_begin, 
      const typename std::map<T1,T2>::const_iterator& input_end) 

類型T1T2不能從調用的地方的說法推斷。這是在標準中定義的,如果你考慮它(在一般情況下)它是有道理的。

請注意,您不是std::map<>::const_iterator而是sometemplate<T>::nested_type,並且在通話地點的參數是int。如果編譯器必須推導出類型,則必須爲宇宙中的所有可能類型T(無限集)實例化sometemplate,並查找其中哪些嵌套類型nested_typeint的類型定義。

正如有人在評論中指出的那樣,你可以改變模板,以便代替模板化地圖的鍵和值類型,它只需要迭代器。


委派值

這種提取是一個解決方法,以提供一個實現Sum,可以處理順序和關聯容器。

namespace detail { 
template <typename T> T valueOf(T const & t) { return t; } 
template <typename K, typename V> 
V valueOf(std::pair<const K, V> const & p) { 
    return p.second; 
} 
} 
template <typename Iterator> 
double Sum(Iterator begin, Iterator end) { 
    double result = 0; 
    for (; begin != end; ++begin) { 
    result += detail::valueOf(*begin); 
    } 
    return result; 
} 

我還沒有測試代碼,但應該這樣做。這可能比在Sum模板上使用SFINAE簡單得多。

+1

所有類型的集合都遠非無限且編譯器可能有它們的列表。問題是像這樣的每個「間接」都會使複雜度乘以類型數量。 – Dani

+0

@Dani:一旦你有一個模板,只考慮基本類型'int'和容器'std :: vector'(忽略分配器類型),**類型的集合**是無限的,你可以有:'int' ,'std :: vector ','std :: vector >'...並且您可以根據需要嵌套儘可能多的類型,只需從一個基本類型和一個模板中生成無限數量的類型。正如你所說,它也涉及複雜性的非線性增長,但即使是線性也是棘手的。 –

+0

我爲矢量和其他順序容器編寫的總和函數已經在迭代器上模板化了。只是爲了處理我編寫過載版本的地圖。 (我的一般功能): 模板雙總和(常量T&input_begin,常量T&input_end) @Jason: 我已經重寫SUM函數作爲一個普通的重載函數,沒有模板。那是你的意思嗎? (const std :: map :: const_iterator&input_begin,const std :: map :: const_iterator&input_end) 它工作正常。試圖理解整個事情。 – NotAgain

相關問題