I would like to write a generic function that takes some map-like type, and returns all the keys in the map. I would also like the API of the function to be extremely simple, like this:
std::unordered_map<int, std::string> stringTable;
auto stringTableKeys = keys(stringTable); // should return a std::vector<int>
std::map<std::string, double> doubleTable;
auto doubleTableKeys = keys(doubleTable); // should return a std::vector<std::string>
I don't want it to be tied down to std::map or std::unordered_map, nor do I want to be tied down to specific key or value types, so I tried to write the following:
template <typename Key, typename Value, template <typename, typename...> typename Table>
std::vector<Key> keys(const Table<Key, Value>& table)
{
std::vector<Key> keys;
keys.reserve(table.size());
for (const auto& [key, value] : table)
keys.push_back(key);
return keys;
}
However, if I want to use this version of the keys() function, I have to call it like this
auto stringTableKeys = keys<int, std::string, std::unordered_map>(stringTable);
How can I specify the template in the definition of keys() so that the caller does not have to specify the types?