使用比较器进行STL设置
检查以下代码:
string toLowerCase(const string& str) {
string res(str);
int i;
for (i = 0; i < (int) res.size(); i++)
res[i] = (char) tolower(res[i]);
return res;
}
class LeagueComparator
{
public:
bool operator()(const string& s1, const string& s2)
{
return toLowerCase(s1) < toLowerCase(s2);
}
};
int main()
{
set<string, LeagueComparator> leagues;
set<string, LeagueComparator>::iterator iter;
leagues.insert("BLeague");
leagues.insert("aLeague"); // leagues = {"aLeague", "BLeague"}
leagues.insert("ALeague");
for (iter = leagues.begin(); iter != leagues.end(); iter++)
cout << *iter << endl;
return 0;
}
输出是:
aLeague
BLeague
这让我感到震惊。我认为(并期望)输出将是:
aLeague
ALeague
BLeague
在执行 leagues.insert("ALeague");
之前,leagues
包含 "aLeague"和<代码>“BLeague”。我的问题是,在执行
leagues.insert("ALeague");
时,为什么机器会处理 "ALeague" == "aleague"
?据我了解,leagues
中没有"ALeague"
元素。所以“ALeague”
应该插入到leagues
中。比较器应确定在何处放置“ALeague”
。
提前致谢。
PS:请不要因为我使用C风格演员而打我。 :P 我懒得输入static_cast
。
Check the following code:
string toLowerCase(const string& str) {
string res(str);
int i;
for (i = 0; i < (int) res.size(); i++)
res[i] = (char) tolower(res[i]);
return res;
}
class LeagueComparator
{
public:
bool operator()(const string& s1, const string& s2)
{
return toLowerCase(s1) < toLowerCase(s2);
}
};
int main()
{
set<string, LeagueComparator> leagues;
set<string, LeagueComparator>::iterator iter;
leagues.insert("BLeague");
leagues.insert("aLeague"); // leagues = {"aLeague", "BLeague"}
leagues.insert("ALeague");
for (iter = leagues.begin(); iter != leagues.end(); iter++)
cout << *iter << endl;
return 0;
}
The output is:
aLeague
BLeague
which is shocking to me. I thought (and expecting) the output would be:
aLeague
ALeague
BLeague
Before the execution of leagues.insert("ALeague");
, the leagues
contains "aLeague"
and "BLeague"
. My question is, while executing leagues.insert("ALeague");
why the machine treats "ALeague" == "aleague"
? According to my understanding, there is no element "ALeague"
in leagues
. So "ALeague"
should be inserted into leagues
. The comparator should determine where to put "ALeague"
.
Thanks in advance.
PS: Please don't hit me for using C style cast. :P I'm too lazy to type static_cast
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
由于
toLowerCase
,您的比较器表示"aLeague" == "ALeague"
。因为(根据您的比较器)"aLeague" < "ALeague" == false
和"ALeague" < "aLeague" == false
,它们必须是等价的。将等效元素插入集合中不会执行任何操作。Your comparator, thanks to the
toLowerCase
, says that"aLeague" == "ALeague"
. Since (according to your comparator)"aLeague" < "ALeague" == false
and"ALeague" < "aLeague" == false
, they must be equivalent. And inserting an equivalent element into a set doesn't do anything.当您向集合中插入任何值时,该对象会检查它是否已包含该值。您的
LeagueComparator
对象将ALeague
与集合中已有的其他两个值进行比较。它确定现有值aLeague
既不大于也不小于建议的新条目 (ALeague
),因此它们必须相等,因此不会继续插入物。该集合仍然只有两个元素。这就是提供客户比较对象的全部意义,因此您可以控制集合如何确定两个元素是否匹配。When you insert any value to a set, the object checks to see whether it already contains that value. Your
LeagueComparator
object comparesALeague
with the other two values already in the set. It determines that the existing valueaLeague
is neither greater than nor less than the proposed new entry (ALeague
), so they must be equal, and so it doesn't proceed with the insert. The set remains with just two elements. That's the whole point of providing a customer comparison object, so you can control how the set determines whether two elements match.鉴于您提供的比较器,“ALeague”确实相当于“aLeague”。
给定两个值 x 和 y 以及小于比较器 z:
Given the comparator you provided, "ALeague" is indeed equivalent "aLeague".
Given two values, x and y, and a less-than comparator z:
将您的
LeagueComparator
替换为Replace your
LeagueComparator
with