为什么std :: sort无法找到适当的(静态成员)函数重载?

时间:2018-09-24 08:34:06

标签: c++ visual-c++ stl overloading

我有一个提供自定义静态比较器的类,供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找不到匹配的过载?

2 个答案:

答案 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#,在类似情况下也会出现高度特有的错误。