C++ implicit/explicit 模板方法专业化问题
C++ implicit/explicit template method specialization issue
我在调用函数时遇到问题:
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)
谢谢大家!
你的 std::function<bool(Elem, Elem)> comparator
应该是
std::function<bool(const Elem&, const Elem&)>
或 std::function<bool(auto,auto)>
如果您使用的是 C++14。
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命名空间中,需要命名空间限定。
可以对您的签名做一个小改动,将 Compare 作为另一个模板参数:
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) {
// ...
}
我在调用函数时遇到问题:
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)
谢谢大家!
你的 std::function<bool(Elem, Elem)> comparator
应该是
std::function<bool(const Elem&, const Elem&)>
或 std::function<bool(auto,auto)>
如果您使用的是 C++14。
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命名空间中,需要命名空间限定。
可以对您的签名做一个小改动,将 Compare 作为另一个模板参数:
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) {
// ...
}