Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type-based templating function in C++

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?

like image 708
Schubi Duah Avatar asked Aug 14 '15 10:08

Schubi Duah


1 Answers

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

DEMO 1

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

DEMO 2

like image 181
Piotr Skotnicki Avatar answered Sep 18 '22 15:09

Piotr Skotnicki