user17198641
user17198641

Reputation:

Why is max_element not showing the largest string in vector C++?

In the code below I attempt to print the largest std::string in a std::vector using std::max_element.

I expected the output of the code below to be:

Harmlessness

The actual output I got is:

This

The code:

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main(){
    vector <string> strlist;
    strlist.push_back("This");
    strlist.push_back("Harmless");
    strlist.push_back("Harmlessness");
    cout << *max_element(strlist.begin(), strlist.end());
    return 0;
}

My question:
Can you explain why the code produced the actual output above and not the one I expected ?

Upvotes: 0

Views: 128

Answers (1)

wohlstad
wohlstad

Reputation: 28084

The default comparator for std::string does an lexicographic comparison (see: std::string comparators).

The string "This" comes later in this order than any string starting with "H".

You can use another overload of std::max_element that accepts an explicit comparator argument:

template<class ForwardIt, class Compare> constexpr ForwardIt max_element( ForwardIt first, ForwardIt last, Compare comp);

If you want to compare strings by length, you can use:

#include <iostream>
#include <algorithm>
#include <vector>

int main() {
    std::vector <std::string> strlist;
    strlist.push_back("This");
    strlist.push_back("Harmless");
    strlist.push_back("Harmlessness");
    
    // Use an explicit comparator, in this case with a lambda:
    std::cout << *max_element(strlist.begin(), strlist.end(), 
                         [](std::string const& a, std::string const& b) {return a.length() < b.length(); });
    return 0;
}

Output:

Harmlessness

Side note: better to avoid using namespace std - see here Why is "using namespace std;" considered bad practice?.

Upvotes: 4

Related Questions