Допустим, я хочу, чтобы ключом в unordered_map выступала пара строки и числа.
Что-то вроде std::unordered_map<std::tuple<std::string, int>, MyStruct>. Хеширование легко можно реализовать следуя советам из https://stackoverflow.com/questions/7110301/generic-hash-for-tuples-in-unorde....
А вот дальше возникает проблема. Чтобы сделать find требуется создать экземпляр ключа для поиска. Так как ключ включает в себя строку, произойдёт копирование (допустим, наша функция получает const std::string& и должна действовать), что не есть хорошо.
Какое представление строки не требует копирование при создании? Правильно, std::string_view. Давайте сделаем ключом std::tuple<std::string_view, int>. Теперь операция поиска будет очень дешёвой.
Однако, возникает проблема как вставить в коллекцию новый элемент. Ведь string_view не хранит строку, а лишь ссылку на неё. Логичным решением выглядит сохранить строку в значении. Изменим тип коллекции на std::unordered_map<std::tuple<std::string_view, int>, std::tuple<std::string, MyStruct>>.
Надо чтобы string_view из ключа ссылался на string из значения. Тогда можно будет искать по легковесному ключу std::tuple<std::string_view, int>, а копированием заниматься лишь при добавлении элемента.
Но... Но как сделать так, чтобы string_view ссылался куда надо в момент insert/emplace?
Или, возможно, я что-то делаю не так и использую не те структуры данных.
P.S.: tuple здесь для простоты, на его месте, разумеется может быть своя структура из двух полей с определенным оператором сравнения и хеширования.