[英]Type-based templating function in C++
I want to write a function that fail-safe accesses std::map
. 我想编写一个故障安全访问
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"). 在我的代码中的许多地方我想通过键访问
std::map
,但是如果键不存在,我希望有一种默认值而不是异常(这是很多代码“)。
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. 但是对于
std::map<int, const char*>
我想有不同的行为。 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*>
? 有没有人知道如何在没有将defaultValue设置为
""
情况下保存行,以便调用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? 有没有办法在编译时区分类型,可能有一些
ifdef
或类似的东西?
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>();
}
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");
}
Thank you so much! 非常感谢! I did not see this simple but very effective possibilites.
我没有看到这种简单但非常有效的可能性。
Combining the two methods while adding the functionality of situation based different defaultValue I did finnally do this: 结合这两种方法,同时添加基于不同defaultValue的情境功能,我最终做到了这一点:
template <typename T>
constexpr T mapGetByKeyDefaultValue()
{
return {};
};
template <>
constexpr const char* mapGetByKeyDefaultValue<const char*>()
{
return "";
};
template <typename T1, typename T2>
T2 mapGetByKey(std::map<T1, T2>& map, T1 key, T2 defaultValue=mapGetByKeyDefaultValue<T2>())
{
auto it = map.find(key);
if (it != map.end())
{
return it->second;
};
return defaultValue;
};
You can add a template function for the default value, and add its specialized version for the specific type: 您可以为默认值添加模板函数,并为特定类型添加其专用版本:
template <typename T>
T default_value() { return {}; }
template <>
const char* default_value<const char*>() { return ""; }
And then 接着
template <typename T1, typename T2>
T2 mapGetByKey(std::map<T1, T2>& map, T1 key, T2 defaultValue=default_value<T2>())
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.