返回引用到原始参数



我具有这样的函数

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只是从中阅读。

相关内容

最新更新