模板函数从多个嵌套的unordered_map的值中提取值

Pav*_*tov 4 c++ recursion templates variadic-templates

假设我有一个std::unordered_map看起来像这样的嵌套:

std::unordered_map<ResourceName, std::unordered_map<HAL::ResourceFormat::Color, HAL::RTDescriptor>>
Run Code Online (Sandbox Code Playgroud)

我想要一个函数,该函数将HAL::RTDescriptor基于两个键ResourceName以及HAL::ResourceFormat::Color是否存在对象返回一个指向的指针nullptr。简单的实现如下所示:

const HAL::RTDescriptor* ResourceDescriptorStorage::GetRTDescriptor(ResourceName resourceName, HAL::ResourceFormat::Color format) const
    {
        auto mapIt = mRTDescriptorMap.find(resourceName);

        if (mapIt == mRTDescriptorMap.end()) {
            return nullptr;
        }

        auto& nestedMap = mapIt->second;
        auto nestedMapIt = nestedMap.find(format);

        if (nestedMapIt == nestedMap.end()) {
            return nullptr;
        }

        return &nestedMapIt->second;
    }
Run Code Online (Sandbox Code Playgroud)

有没有办法使用模板来概括逻辑?一些带有参数包的键。将在每个嵌套容器中进行检查,检查对象是否可用,然后将其返回或nullptr在末尾返回:

template<
        template<class...> class AssociativeContainer,
        class... Keys
    >
        decltype(auto) Find(const AssociativeContainer<...>& rootContainer, Keys&&... keys)
    {
        ...
    }
Run Code Online (Sandbox Code Playgroud)

kri*_*isz 6

更简单的解决方案(需要C ++ 17):

template<class AssociativeContainer, class Key, class... Keys>
auto Find(const AssociativeContainer& container, Key&& key, Keys&&... keys){
    auto it = container.find(std::forward<Key>(key));
    bool found = it != container.end();
    if constexpr(sizeof...(Keys) == 0)
        return found ? &it->second : nullptr;
    else
        return found ? Find(it->second, std::forward<Keys>(keys)...) : nullptr;
}
Run Code Online (Sandbox Code Playgroud)

这还允许获取对任何中间容器的引用,因为它不需要传递所有键。