0

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 ?

wohlstad
  • 12,661
  • 10
  • 26
  • 39

1 Answers1

5

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?.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
wohlstad
  • 12,661
  • 10
  • 26
  • 39