Using a comparator for an STL set

Check out 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;
}

Conclusion:

aLeague
BLeague

which is shocking me. I thought (and expected) the output:

aLeague
ALeague
BLeague

It leagues.insert("ALeague"); leaguescontains "aLeague"and before execution "BLeague". My question is, at runtime, leagues.insert("ALeague");why does the machine process "ALeague" == "aleague"? In my opinion, there is leaguesno element "aLeague". Therefore "aLeague", insert into leagues. The comparator must determine where to put it "aLeague".

Thanks in advance.

PS: Please don't hit me for using the C: style. P I'm too lazy to type static_cast.

+5
source share
4 answers

, toLowerCase, , "aLeague" == "ALeague". ( ) "aLeague" < "ALeague" == false "aLeague" < "ALeague" == false, . .

+14

- , , . LeagueComparator ALeague , . , ALeague (ALeague), , . . , , , , .

+4

, "ALeague" "aLeague".

, , , z:

  • z (x, y) , x y
  • z (y, x) , y x
  • , x y
  • , .
+3
source

Replace LeagueComparatorwith

class LeagueComparator
{
public:
    bool operator()(const string& s1, const string& s2)
    {
        return toLowerCase(s1) < toLowerCase(s2)   ||  
               !(toLowerCase(s2) < toLowerCase(s1))  &&  s1 < s2;
    }
};
0
source

All Articles