2016-03-08 36 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,更大的())调用时,通过明确指定类型来解决此问题。 –

相关问题