我具有这样的函数
template<typename T>
const T& get(std::string key, T defaultValue)
{
try {
return getFromMap<T>(key);
}
catch (const std::exception &e)
{
return defaultValue;
}
}
从混合类型映射中检索键入的值,如果找不到键,则返回DefaultValue。地图中有原始类型为值(因此我们必须返回对该值的引用)。我们只需要担心原始默认值即可。与我们的对象值一起使用它是不支持的。该功能在Linux上正常工作,但是在Windows上运行时,我的返回默认值是垃圾。例如,
获取("失踪",true)返回false(IE 0)
get("失踪",3.14)返回0
get("丢失"," mydefault")返回垃圾地址
等等。我想问题是类似的是,默认值正在复制到功能内的新变量中,然后返回对临时的引用。如何修复我的功能以在Windows上做正确的事情?
首先,无论操作系统如何,您的功能都会损坏。原因是当发生异常情况时,它具有未定义的行为:您正在返回对功能 - 局部对象的引用(参数defaultValue
)。函数退出后,这种参考就会立即悬挂,并且通过悬挂参考访问对象的是UB。它碰巧在Linux上工作只是不幸的运气,并且可以通过更改编译器版本,编译开关,源代码的其他部分或其他任何内容来轻松破坏。
恐怕您面临的问题没有快速&amp;清洁。
我认为您最好通过提供两个get
的过载,一种用于原始类型,一种将按值返回,一种用于通过const T &
返回的非主要类型(并且不支持默认值,您提到的是可以给你)。您可以这样进行:
template<typename T, typename = std::enable_if_t<std::is_fundamental<T>::value>>
T get(const std::string &key, T defaultValue)
{
try {
return getFromMap<T>(key);
}
catch (const std::exception &e)
{
return defaultValue;
}
}
template<typename T, typename = std::enable_if_t<!std::is_fundamental<T>::value>>
const T& get(const std::string &key)
{
return getFromMap<T>(key);
}
请注意,我将get
更改为const&
的key
参数。如果您担心性能,则不应复制key
只是从中阅读。