C++隐式/显式模板方法专用化问题



我在调用函数时遇到问题:

namespace Sort {
enum Type {
insertion, selection, merge
};
template <class Elem = int, class Container = std::vector<Elem>>
void sort(std::shared_ptr<Container> vectorPointer,
std::function<bool(Elem, Elem)> comparator = std::less<Elem>(),
Type type = selection) {
switch (type) {
case insertion:
insertionSort(vectorPointer, comparator);
case selection:
selectionSort(vectorPointer, comparator);
case merge:
mergeSort(vectorPointer, comparator);
}
}
}

当我这样称呼它时:

std::shared_ptr<std::vector<int>> intVector;
Sort::sort(intVector);

一切都很好,但是如果我开始替换默认参数:

Sort::sort(intVector, std::less<int>(), merge);

我收到一条错误消息:Candidate template ignored: could not match 'function' against 'less'

更新:

我终于让它工作了 - 明确地专门化函数调用似乎可以解决问题。另外,我没有提供枚举值的命名空间。

Sort::sort<int, std::vector<int>>(intVector, std::less<int>(), Sort::merge)

谢谢大家!

template <class Elem = int, class Container = std::vector<Elem>>
void sort(std::shared_ptr<Container> vectorPointer,
std::function<bool(Elem, Elem)> comparator = std::less<Elem>(),
Type type = selection)

比较器类型取决于模板参数 Elem,因此当编译器执行模板推导规则时,它要求调用方提供的值具有与参数的类型模式匹配的类型。 由于"less"和"function"不是同一类型,因此此函数不是有效的匹配。

(不要将类型推断逻辑与处理这些类型的实例时允许的转换序列混淆。

如果您将呼叫更改为如下所示,它将起作用(尽管由于糟糕的用户体验,显然您不想这样做):

Sort::sort(shV, std::function<bool(int, int)>(std::less<int>()), Sort::merge);

这样,第二个参数的类型与模板的期望相匹配。 上面的示例还解决了"merge"枚举器的使用问题,该枚举器位于 Sort 命名空间中,需要命名空间限定。

对签名进行一个小的更改,将比较作为另一个模板参数,是可能的:

template <class Elem = int, class Container = std::vector<Elem>, 
class Compare = std::less<Elem>>
void sort(std::shared_ptr<Container> vectorPointer,
Compare comparator = Compare(),
Type type = selection) {
switch (type) {
// ...
}

你的std::function<bool(Elem, Elem)> comparator应该是std::function<bool(const Elem&, const Elem&)>std::function<bool(auto,auto)>如果您使用的是 C++14。

最新更新