簡體   English   中英

C ++中基於類型的模板函數

[英]Type-based templating function in C++

我想編寫一個故障安全訪問std::map的函數。

在我的代碼中的許多地方我想通過鍵訪問std::map ,但是如果鍵不存在,我希望有一種默認值而不是異常(這是很多代碼“)。

我寫了這個基於模板的功能

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或類似的東西?

選項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

非常感謝! 我沒有看到這種簡單但非常有效的可能性。

結合這兩種方法,同時添加基於不同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;
};

您可以為默認值添加模板函數,並為特定類型添加其專用版本:

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

生活

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM