2016-03-08 62 views
3

我已經在C++中定義的以下功能:模板與函數類型參數的原因編譯器錯誤

template<class Type> Type GetMedian(const vector<Type>& items, function<bool(Type, Type)> comp) { 
    vector<Type> copied_items(items); 
    std::nth_element(copied_items.begin(), copied_items.begin() + copied_items.size()/2, copied_items.end(), comp); 
    return copied_items[copied_items.size()/2]; 
} 

然而,當我試圖把它叫爲GetMedian(v, greater<uint32_t>()),我的編譯器(鐺)抱怨:

error: no 
     matching function for call to 'GetMedian' 
    GetMedian(v, greater<uint32_t>()); 
    ^~~~~~~~~ 
note: 
     candidate template ignored: could not match 'function' against 'greater' 
template<class Type> Type GetMedian(const vector<Type>& items, function... 

不過,我沒有看到這個錯誤,每當我更改爲不使用模板,如:

uint32_t GetMedian(const vector<uint32_t>& items, function<bool(uint32_t, uint32_t)> comp) { 
    vector<uint32_t> copied_items(items); 
    std::nth_element(copied_items.begin(), copied_items.begin() + copied_items.size()/2, copied_items.end(), comp); 
    return copied_items[copied_items.size()/2]; 
} 

有沒有什麼辦法讓我的功能像我想要的那樣靈活?

+0

您是否希望模板強制執行提供的比較函數與矢量類型相同,或者如果使用不正確的比較函數會生成編譯器錯誤/警告(如果類型不相同),是否可以使用? – NathanOliver

+0

我懷疑這是一個不可推卸的背景問題。您可以通過顯式使用模板參數來解決問題。 'GetMedian (...)'。 –

回答

7

類型Type推導出在這裏有兩個點:

template<class Type> 
Type GetMedian(const vector<Type>& items, function<bool(Type, Type)> comp); 
          ^^^^      ^^^^^^^^^^ 

當你與GetMedian(v, greater<uint32_t>())調用它,它會推斷Typeuint32_tv,但隨後它需要推斷function<bool(Type, Type)>greater<uin32_t>。但後者不是function類型,所以扣除失敗。它是可兌換function<bool(uint32_t, uint32_t)>,但轉換不會在模板扣除過程中發生。

謝天謝地,您實際上並不需要std::function這裏。實際上它更糟糕 - 你無緣無故地給自己抹去類型擦除的開銷。只要有比較爲單獨的模板類型:

template <class T> struct non_deduced { using type = T; }; 
template <class T> using non_deduced_t = typename non_deduced<T>::type; 

template <class T> 
T median(const std::vector<T>&, std::function<bool(non_deduced_t<T>, non_deduced_t<T>)>) 

template <class Type, class Comp> 
Type GetMedian(const vector<Type>& items, Comp comp); 

或者,如果你真的真的真的想要一個std::function,你可以通過像包裹在非推斷上下文Type

現在,允許從std::greater<uint32_t>std::function<bool(uint32_t, uint32_t)>的轉換髮生,因爲它只是vector<T>這是一個推導的上下文,所以編譯器推導出Tuint32_t,然後檢查第二個參數轉換是否工作。

+0

非常感謝。 –

+0

你能解釋爲什麼我也可以解決這個問題嗎?當我將函數作爲GetMedian (v,更大的())調用時,通過明確指定類型來解決此問題。 –

相關問題