7

我想编写一个故障安全访问的函数std::map

在我的代码中的许多地方,我想std::map通过键访问 a,但如果该键不存在,我希望有一种默认值而不是异常(这是很多“无”的代码)。

我写了这个基于模板的函数

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;
};

它工作得很好。但是对于一个std::map<int, const char*>我想有不同的行为。所以我可以添加这个专业:

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;
};

它也有效。但我认为这只是一个案例的大量代码。

有没有人知道如何在不设置 defaultValue 的情况下保存线路以""进行呼叫std::map<int, const char*>

有没有办法在编译时区分类型,也许有一些ifdef或类似的东西?

4

3 回答 3

4

选项1

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>();
}

演示 1

选项#2

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");
}

演示 2

于 2015-08-14T10:23:38.070 回答
1

太感谢了!我没有看到这种简单但非常有效的可能性。

结合这两种方法,同时添加基于情况的不同 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;
};
于 2015-08-14T10:30:54.813 回答
0

您可以为默认值添加模板函数,并为特定类型添加其专用版本:

template <typename T>
T default_value() { return {}; }
template <>
const char* default_value<const char*>() { return ""; }

接着

template <typename T1, typename T2>
T2 mapGetByKey(std::map<T1, T2>& map, T1 key, T2 defaultValue=default_value<T2>())

居住

于 2015-08-14T10:27:14.483 回答