I want to write a function that fail-safe accesses std::map
.
At many places in my code I want to access a std::map
by key, but in case the key does not exist, I want to have a kind of default value instead of an exception (which is a lot of code for "nothing").
I wrote this template based function
template <typename T1, typename T2>
T2 mapGetByKey(std::map<T1, T2>& map, T1 key, T2 defaultValue={})
{
auto it = map.find(key);
if (it != map.end())
{
return it->second;
}
return defaultValue;
};
It works great. But for a std::map<int, const char*>
I would like to have a different behaviour. So I could add this specialization:
template <typename T1>
const char* mapGetByKey(std::map<T1, const char*>& map, T1 key, const char* defaultValue="")
{
auto it = map.find(key);
if (it != map.end())
{
return it->second;
}
return defaultValue;
};
It works, too. But I think it's a lof of code for just one case.
Does anybody have an idea how to save lines without settings the defaultValue to ""
for calls on std::map<int, const char*>
?
Is there a way to have differentiate between types at compile time, maybe with some ifdef
or something like that?
template <typename T>
T defaultValue()
{
return {};
}
template <>
const char* defaultValue<const char*>()
{
return "default string";
}
template <typename T1, typename T2>
T2 mapGetByKey(std::map<T1, T2>& map, const T1& key)
{
auto it = map.find(key);
if (it != map.end())
{
return it->second;
}
return defaultValue<T2>();
}
DEMO 1
template <typename T> struct identity { using type = T; };
template <typename T1, typename T2>
T2 mapGetByKey(std::map<T1, T2>& map, T1 key, const typename identity<T2>::type& defaultValue = {})
{
auto it = map.find(key);
if (it != map.end())
{
return it->second;
}
return defaultValue;
}
template <typename T1>
const char* mapGetByKey(std::map<T1, const char*>& map, const T1& key)
{
return mapGetByKey(map, key, "default string");
}
DEMO 2
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With