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)
更简单的解决方案(需要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)
这还允许获取对任何中间容器的引用,因为它不需要传递所有键。