2017-02-23 105 views
1

我有一個STL樣列表容器定義了以下兩個功能:錯誤模板函數被調用

// copy the specified VALUE some COUNT number of times and insert copies 
// right before POS. 
Iterator insert(Iterator pos, size_type count, const value_type 
      &value); 

// copy the values from [FIRST, LAST) from the specified Iterators and 
// place before POS. 
template<class InputIt> 
    Iterator insert(Iterator pos, InputIt first, InputIt last); 

然後我試着用一些任意的代碼來測試我的功能實現:

std::list<int> stlList = { 1, 2, 3, 4, 5 }; 
MyList<int> intList; 

intList.insert(intList.begin(), 5, 0); // expected call to first insert 
intList.insert(intList.begin(), stlList.begin(), stlList.end()); // expected call to second insert 

但是,對於他們來說,這似乎是第二個函數被調用。我發現模糊不清,因爲這兩個函數都有三個參數,我看到編譯器可能會調用錯誤的函數。但我不確定我錯過了什麼。我一直以STL爲基礎開發自己的功能,並且據我所知,他們以幾乎相同的方式定義它們(STL's List Insert)。

+0

什麼是'size_type'定義爲? – NathanOliver

+0

我認爲你的'size_type'是無符號的,所以模板方法是完全匹配的。你可以調用'intList.insert(intList.begin(),5u,0)' – Jarod42

+0

注意關於'std :: list :: insert'的重載(4)(帶有兩個迭代器的那個):「這個過載只有當InputIt符合InputIterator的條件時纔會參與重載解析,以避免過載帶來的不確定性(3)。「 –

回答

2

原因intList.insert(intList.begin(), 5, 0);的動產

template<class InputIt> 
Iterator insert(Iterator pos, InputIt first, InputIt last); 

Iterator insert(Iterator pos, size_type count, const value_type &value); 

是因爲模板函數產生一個精確匹配。

50具有相同的類型,以便InputIt被推斷爲int這使得功能樣子

Iterator insert(Iterator pos, int first, int last); 

如果你的另一超載看起來像

Iterator insert(Iterator pos, size_t first, int last); 

正如你可以看到沒有轉換需要調用模板推導的版本,所以它比非模板過載更受歡迎。

如果InputIt確實是一個迭代器,您必須將5轉換爲size_t以使其調用非模板過載或使用SFINAE僅調用模板過載。

2
template<class InputIt> 
    Iterator insert(Iterator pos, InputIt first, InputIt last); 

該模板定義了一個函數,其第二個和第三個參數是相同的類型。你在腦海中假設第二個和第三個參數必須是迭代器。但是這裏沒有這樣的要求,只是第二個和第三個參數的類型必須相同。模板參數的名稱「InputIt」是無關緊要的。

intList.insert(intList.begin(), 5, 0); // expected call to first insert 

第二和第三參數,以該函數調用是相同的類型:一個int。過載分辨率的另一個候選:

Iterator insert(Iterator pos, size_type count, const value_type 
     &value); 

這一個對第二個和第三個參數有不同的類型。雖然這兩個ints都可以在這裏轉換,但另一個模板函數是更好的匹配,因此它被選中。