【问题标题】:std::set comparator error: "invalid operator<"std::set 比较器错误:“无效的运算符<”
【发布时间】:2015-02-14 21:12:49
【问题描述】:

所以我为 std::set 创建了一个自定义比较器。代码如下:

class Identifier
{
    std::string nameID;

public:
    std::string NameID() const
    {
        return this->nameID;
    }
};

class IdentifierSorter
{
    static bool icompare_pred(unsigned char a, unsigned char b)
    {
        return std::tolower(a) == std::tolower(b);
    }

    bool icompare(const std::string& a, const std::string& b)
    {
        return std::lexicographical_compare(a.begin(), a.end(),
            b.begin(), b.end(), icompare_pred);
    }

    bool operator()(const Identifier& id1, const Identifier& id2)
    {
        std::string id1n = id1.NameID();
        std::string id2n = id2.NameID();
        return icompare(id1n, id2n);
    }
};

....

std::set<Identifier, IdentifierSorter> Identifiers;

在我尝试这样做之前一切正常:

auto it = Identifiers.find(someIdentifier);

我收到一个运行时错误,内容如下:

Program: C:\Windows\system32\MSVCP120D.dll
File: c:\program files (x86)\microsoft visual studio   12.0\vc\include\xutility
Line: 2941

Expression: invalid operator<

我不确定出了什么问题。我是否错误地实现了 Comparator?

【问题讨论】:

  • 您应该将该代码简化为最小示例,它既有过多的代码,也有丢失或损坏的代码。就目前而言,它被认为是题外话。
  • 字符串包含字符而不是无符号字符。使用字符串的 const 引用来避免复制。

标签: c++ set comparator


【解决方案1】:

您的代码不起作用,因为您的比较提供了相等性,而算法 (lexicographical_compare) 需要一个关系。

return std::tolower(a) < std::tolower(b);

顺便说一句:查看该错误消息的来源。它应该告诉您谓词无效。在网络上搜索“严格的弱排序”,这应该会为您提供进一步的提示,了解其工作原理和原因。

【讨论】:

  • 这不会阻止它编译。
  • 我猜他从“已检查”的标准库中得到了一个运行时错误。
  • 有趣的是,我没有注意到 OP 指的是运行时错误。所以你很可能是正确的,在这种情况下!
【解决方案2】:

谓词的方法必须是公开的:

class IdentifierSorter
{
    public:

    static bool icompare_pred(unsigned char a, unsigned char b)
    {
        return std::tolower(a) == std::tolower(b);
    }

    bool icompare(const std::string& a, const std::string& b)
    {
        return std::lexicographical_compare(a.begin(), a.end(),
            b.begin(), b.end(), icompare_pred);
    }

    bool operator()(const Identifier& id1, const Identifier& id2)
    {
        std::string id1n = id1.NameID();
        std::string id2n = id2.NameID();
        return icompare(id1n, id2n);
    }
};

除了那个谓词应该表现得像std::less,而不是

static bool icompare_pred(unsigned char a, unsigned char b)
{
    return std::tolower(a) == std::tolower(b);
}

你想要的

static bool icompare_pred(unsigned char a, unsigned char b)
{
    return std::tolower(a) < std::tolower(b);
                       // ^^^
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-14
    • 1970-01-01
    • 2017-07-28
    • 2011-05-13
    相关资源
    最近更新 更多