2012-10-01 57 views
0

我想重載一個Sum函數,它接受[list或vector]開始和結束迭代器作爲參數。這個編譯器錯誤讓我很困惑。相關代碼如下:函數重載,無法推導模板參數

template <typename T1, typename T2> 
const double Sum(const typename T1::const_iterator& start_iter, const typename T2::const_iterator& end_iter) 
{// overloaded function that calculates sum between two iterators 
    typename T1::const_iterator iterator_begin = start_iter; 
    typename T2::const_iterator iterator_end = end_iter; 

    double my_sum = 0; 

    for (iterator_begin; iterator_begin != iterator_end; iterator_begin++) 
     my_sum += *iterator_begin; 

    return my_sum;  
} 

int main() 
{ 

list<double> test_list(10,5.1); 
cout << Sum(test_list.begin(), test_list.end()); // compiler errors here 

} 

我得到以下編譯器錯誤:

iterators.cpp(72):錯誤C2783:「常量雙總和(常量 T1 ::爲const_iterator &,常量T2 ::爲const_iterator &) ':無法推斷 模板參數關於 'T1'

iterators.cpp(72):錯誤C2783:' const的雙薩姆(常量 T1 ::爲const_iterator &,常量T2 ::爲const_iterator &)」:無法推斷 模板參數關於 'T2'

iterators.cpp(72):錯誤C2780: 'const的雙薩姆(常量 的std ::地圖&)':期望1個參數 - 2提供

iterators.cpp(72):錯誤C2780: 'const的雙薩姆(常量Ť&)': 期望1個參數 - 2提供

如何編譯器不能識別我試圖用兩個輸入調用Sum函數?我錯誤地調用了該函數?

謝謝!

回答

5

你不需要告訴它的迭代器必須是某些類型的T1T2的成員,只是模板它的迭代器類型本身:

template <typename Iter> 
const double Sum(Iter iterator_begin, Iter iterator_end) 
{ 
    double my_sum = 0; 
    for (; iterator_begin != iterator_end; ++iterator_end) 
     my_sum += *iterator_begin; 
    return my_sum;  
} 

int main() 
{ 
    std::list<double> test_list; 
    std::cout << Sum(test_list.begin(), test_list.end()); 
    return 0; 
} 

也有一個標準std::accumulate這樣做:

int main() 
{ 
    std::list<double> test_list; 
    std::cout << std::accumulate(test_list.begin(), test_list.end(), 0.0); 
    return 0; 
} 
+0

我怎麼能讓他們保持常量? –

+0

@Clark你不能。你可能不想;迭代器和const_iterator之間的區別在很多情況下是不相關的(例如輸入迭代器)。如果將模板記錄爲接受輸入迭代器('template ',而不是'Iter'),那麼很明顯該函數不會改變序列。否則,你記錄它沒有。 –

+0

非常感謝。 –

2

調用方法這樣的..

Sum<list<double>,list<double> >(test_list.begin(), test_list.begin()); 
+0

哦,非常感謝! –

4

首先,我認爲你不想這樣做。並非所有的序列都有一個 潛在的容器。 (例如,想想istream_iterator s)。更重要的是,你明顯允許(甚至鼓勵) 開始和結束來自不同容器的迭代器;有沒有的情況下 在那裏你可以合法使用這個功能,其中T1T2有 不同類型。該模板應該有一個參數,其中 應該是一個迭代器;按照慣例,迭代器的約束條件應該用參數的名稱來表示,例如, InputIterator(這裏的情況),ForwardIterator

至於爲什麼你的代碼不能編譯:

在大多數情況下,使用 的類型,模板和非類型值組成P參與模板論證推演。也就是說,它們可以用於確定模板參數的值,並且如此確定的值必須與其他地方確定的值 一致。然而,在某些情況下,值不是 參與類型推斷,而是使用模板 參數的值,這些參數可以在別處推導或明確指定。 如果模板參數僅用於未推演的上下文,並且未明確指定 ,則模板參數推演失敗。

非推導上下文是:

- 被使用 合格-id指定的類型的嵌套名稱說明符。

[...]

(從§14.8.2.5/ 4,5)。