std::set comparator error: "invalid operator<"
std::set comparator error: "invalid operator<"
所以我为 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<
我不确定哪里出了问题。我是否错误地实现了比较器?
谓词的方法必须是public:
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);
// ^^^
}
您的代码不起作用,因为您的比较提供了类似相等性的东西,而算法 (lexicographical_compare) 需要一个关系。
return std::tolower(a) < std::tolower(b);
顺便说一句:查看该错误消息的来源。它应该告诉您谓词无效。在网络上搜索 "strict weak ordering",这应该会为您提供进一步的提示,说明其工作原理和原因。
所以我为 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<
我不确定哪里出了问题。我是否错误地实现了比较器?
谓词的方法必须是public:
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);
// ^^^
}
您的代码不起作用,因为您的比较提供了类似相等性的东西,而算法 (lexicographical_compare) 需要一个关系。
return std::tolower(a) < std::tolower(b);
顺便说一句:查看该错误消息的来源。它应该告诉您谓词无效。在网络上搜索 "strict weak ordering",这应该会为您提供进一步的提示,说明其工作原理和原因。