为什么 std::sort 找不到合适的(静态成员)函数重载?
Why does std::sort fail to find the appropriate (static member) function overload?
我有一个类,它提供了可供std::sort
使用的自定义静态比较器。以下内容可以很好地编译(简化为最小的代码示例(:
#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);
}
现在,当我向 StringUtils 类添加重载时,例如
static bool customStringCompare(const char*, const char*) { return true; }
以下方法将起作用:
void test2()
{
std::string s1, s2;
StringUtils::customStringCompare(s1, s2);
}
但是,上面的std::sort
调用会在 MSVC 2015 Update 2 中生成编译器错误 C2672(未找到匹配的重载(、C2780(预期的 2 个参数 - 支持 3 个(、C2783(无法推断"_Pr"的模板参数(。
为什么在这种情况下std::sort
找不到匹配的重载?
在你的代码中,std::sort
采用函数指针。那么编译器如何决定你想要哪个函数呢?智能感知显示以下错误:
无法确定重载函数
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);
});
}
问题是有两个重载,将一个传递给std::sort
并不能阐明应该使用哪个重载1.编译器无法从std::sort
调用中的用法推断出这一点。这是有道理的:std::sort
的比较器参数的类型只是一个模板参数,即它完全未指定:任何重载都与其他任何重载一样好。
有多种解决方法,在实践中,我通常建议传递一个函子,如 Evg 的答案所示。
但重要的是要了解错误只是由无法自动推断的类型引起的。因此,要使代码编译,显式指定类型就足够了;这将选择单个重载:
std::sort(
testList.begin(),
testList.end(),
static_cast<bool (*)(std::string const&, std::string const&)>(StringUtils::customStringCompare)
);
在这里,我们使用static_cast
来显式指示函数(指针(的类型,以便解决重载问题。
1而且,坦率地说,每个主流编译器都会产生一条烂的错误消息。这早已为人所知,并且是完全可以修复的。clang++比GCC和MSVC略好,但老实说并没有太多。但即使是 C#,一种完全不相关的语言,在类似情况下也会给出非常特殊的错误。
- 如何在C++中使用非静态成员函数作为回调函数
- 静态成员函数使用相同的名称时出现模板类型名称错误
- 在 nullptr 上调用无状态类的非静态成员函数是否合法?
- 为什么传递非静态成员函数会导致编译错误?
- 处理类内的回调时,必须调用对非静态成员函数的引用
- 非静态成员函数的 decltype 格式不正确吗?
- std::异步与非静态成员函数
- C++无效使用非静态成员函数?
- 未使用的C++未优化的静态成员函数/变量
- C++:如何返回指向非静态成员函数的指针?
- 使用静态成员函数而不是普通函数是否有任何开销?
- 在 stream_descriptor::async_wait 中无效使用非静态成员函数
- 为什么我不能像这样在静态成员函数中调用静态成员变量?
- 无法在clang Linux中分配非静态成员函数,但我可以在Visual Studio Windows中分配
- 在类定义中推导内联静态成员函数的返回类型
- `enable_if()`以禁用模板化类的静态成员函数声明
- 错误:无效使用非静态成员函数"int test::hotplug_callback(libusb_contex
- 常量静态成员函数
- 使用 vector.sort() 的非静态成员函数无效使用
- 从静态成员函数访问私有非静态类变量 - C++