我有一个提供自定义静态比较器的类,供android:name
使用。下面的代码可以很好地编译(简化为一个最小的代码示例):
std::sort
现在,当我向
之类的StringUtils类添加重载时#include <vector>
#include <string>
#include <algorithm>
class StringUtils
{
public:
static bool customStringCompare(const std::string&, const std::string&) { return true; }
};
void test()
{
std::vector<std::string> testList;
std::sort(testList.begin(), testList.end(), StringUtils::customStringCompare);
}
以下将起作用:
static bool customStringCompare(const char*, const char*) { return true; }
但是,上面的void test2()
{
std::string s1, s2;
StringUtils::customStringCompare(s1, s2);
}
调用在MSVC 2015中产生编译器错误C2672(未找到匹配的重载),C2780(预期2个参数-支持3个),C2783(无法推导出“ _Pr”的模板参数)更新2。
在这种情况下,为什么std::sort
找不到匹配的过载?
答案 0 :(得分:6)
在您的代码std::sort
中使用一个函数指针。然后,编译器如何确定所需的功能? IntelliSense显示以下错误:
无法确定打算使用哪个重载函数
StringUtils::customStringCompare
要使用重载,可以将比较器转换为功能对象:
struct Comparator {
bool operator()(const std::string&, const std::string&) const {
return true;
}
bool operator()(const char*, const char*) const {
return true;
}
};
void test() {
std::vector<std::string> testList;
std::sort(testList.begin(), testList.end(), Comparator{});
}
或者,从C ++ 14开始,您可以使用通用的lambda函数:
void test() {
std::vector<std::string> testList;
std::sort(testList.begin(), testList.end(),
[](const auto& s1, const auto& s2) {
return StringUtils::customStringCompare(s1, s2);
});
}
答案 1 :(得分:2)
问题在于有两个重载,并且将一个重载传递给func (d *state) Sum(in []byte) []byte {
dup := d.clone()
hash := make([]byte, dup.outputLen)
dup.Read(hash)
return append(in, hash...)
}
并不能说明应该使用哪个重载 1 。编译器无法从std::sort
调用中的用法推断出这一点。这是有道理的:The type of the comparator argument of std::sort
只是一个模板参数,即它是完全未指定的:任何重载都与其他任何参数一样有效。
有多种解决方法,实际上,我通常建议传递一个函子,如Evg的答案所示。
但是重要的是要了解错误是由无法自动推断的类型引起的。因此,要编译代码,只需明确指定类型即可;这将选择一个重载:
std::sort
在这里,为了重载解析,我们使用std::sort(
testList.begin(),
testList.end(),
static_cast<bool (*)(std::string const&, std::string const&)>(StringUtils::customStringCompare)
);
来显式表示函数(指针)的类型。
1 坦率地说,每个主流编译器都会产生错误的错误消息。这已经很久了,并且是完全可以修复的。 clang ++比GCC和MSVC稍好,但说实话也不是很多。但是即使是完全不相关的语言C#,在类似情况下也会出现高度特有的错误。