I am trying to sort a vector of strings using a custom comparator that sorts first by a the string portion then by the numeric portion. However when I try to run the code at the bottom I get the error
terminate called after throwing an instance of 'std::out_of_range'
  what():  basic_string::substr: __pos (which is 2) > this->size() (which is 0)
With some debugging I find that this is a result of my cmp function receiving an empty string. When all the elements of my vector are not empty, why would my cmp function receive an empty string?
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
string get_letter(const string &s) {
    return s.substr(0, 1);
}
unsigned long get_number(const string &s) {
    return stoi(s.substr(2));
}
bool cmp(const string &a, const string &b) {
    bool letter_cmp = get_letter(a) < get_letter(b);
    bool number_cmp = get_number(a) < get_number(b);
    return letter_cmp || number_cmp;
}
int main()
{
    vector<string> vals;
    vals.push_back("X   2805");
    vals.push_back("W   279");
    vals.push_back("O   8667");
    vals.push_back("U   7133");
    vals.push_back("B   654");
    vals.push_back("S   7216");
    vals.push_back("V   6016");
    vals.push_back("H   965");
    vals.push_back("Z   4821");
    vals.push_back("O   4299");
    vals.push_back("Y   3704");
    vals.push_back("U   6526");
    vals.push_back("R   3942");
    vals.push_back("S   3250");
    vals.push_back("E   4319");
    vals.push_back("K   7847");
    vals.push_back("Y   2607");
    vals.push_back("D   8508");
    vals.push_back("F   2846");
    vals.push_back("Z   4069");
    vals.push_back("J   8086");
    vals.push_back("M   2800");
    vals.push_back("B   5983");
    vals.push_back("P   9819");
    vals.push_back("L   1886");
    vals.push_back("C   9269");
    vals.push_back("W   3862");
    vals.push_back("M   9940");
    vals.push_back("B   2236");
    vals.push_back("U   1748");
    vals.push_back("O   7226");
    vals.push_back("H   5304");
    vals.push_back("C   2785");
    vals.push_back("V   2873");
    vals.push_back("V   9744");
    vals.push_back("D   2562");
    vals.push_back("Q   8987");
    vals.push_back("W   8557");
    vals.push_back("J   2045");
    vals.push_back("G   1875");
    vals.push_back("O   627");
    vals.push_back("T   1173");
    vals.push_back("T   1371");
    vals.push_back("V   8724");
    vals.push_back("T   8625");
    vals.push_back("L   2434");
    vals.push_back("H   3669");
    vals.push_back("J   8253");
    vals.push_back("Z   7284");
    vals.push_back("H   9764");
    vals.push_back("G   8312");
    vals.push_back("V   3186");
    vals.push_back("V   7479");
    vals.push_back("J   5610");
    vals.push_back("Q   421");
    vals.push_back("Z   6078");
    vals.push_back("P   3644");
    vals.push_back("C   3690");
    vals.push_back("F   1386");
    vals.push_back("R   7987");
    sort(vals.begin(), vals.end(), cmp);
}
