在C ++中工作,有时候我正在使用嵌套地图。例如,假设:
enum Color { RED, GREEN, BLUE};
enum Shape { CIRCLE, SQUARE, TRIANGLE };
std::unordered_map<Color, std::unordered_map<Shape, int>> shapeColorCount;
对于这些情况,使用可变参数模板来编写以键的类型为模板的setter和getter函数将很有用。目标将是这样的:
template<typename TValue, typename TKeys...>
TValue& nestedGet(MapTypeHere t_map, const TKeys&... t_keys);
void nestedSet(MapTypeHere t_map, const TValue& t_value, const TKeys&... t_keys);
递归地定义这些函数不是很困难,但是我的主要问题是使模板参数的类型推断正常工作。问题是指定MapTypeHere。我几乎可以写类似
template<typename TValue, typename TKey>
using Map = std::unordered_map<TKey, TValue>;
template<typename TValue, typename TOuterKey, typename... TInnerKeys>
using Map = std::unordered_map<TOuterKey, Map<TValue, TInnerKeys...>;
template<typename TValue, typename... TKeys>
TValue& nestedGet(Map<TValue, TKeys...>& t_map, const TKeys&... t_keys);
void nestedSet(Map<TValue, TKeys...>& t_map, const TValue& t_value, const TKeys&... t_keys);
尝试创建使用指令的递归,但它抱怨说,当我尝试使用基本参数作为时,我试图在非包装模板变量中使用参数包装Map
。如果我将它们包装在结构中,似乎允许它使用声明来执行此递归操作,但是然后我遇到了类型推断不起作用的问题。回到上面的例子:
std::unordered_map<Color, std::unordered_map<Shape, int>> shapeColorCount
nestedSet<int, Color, Shape>(shapeColorCount, 5, Color::RED, Shape::SQUARE); // This works
nestedSet(shapeColorCount, 5, Color::RED, Shape::SQUARE); // It can't figure out the types for the template
有没有办法使此设置正常工作?
是的,您可以编写以下函数:
template<typename Map, typename Value, typename FirstKey, typename ...RestKeys>
void nestedSet(Map& map, Value const& value, FirstKey const& key, RestKeys const&... rest_keys)
{
if constexpr(sizeof...(RestKeys) == 0)
map[key] = value;
else
nestedSet(map[key], value, rest_keys...);
}
template<typename Map, typename FirstKey, typename ...RestKeys>
auto& nestedGet(Map& map, FirstKey const& key, RestKeys const&... rest_keys)
{
if constexpr(sizeof...(RestKeys) == 0)
return map[key];
else
return nestedGet(map[key], rest_keys...);
}
请注意,此解决方案不依赖于特定的unordered_map<Color, std::unordered_map<Shape, int>>
实例。它适用于键和值类型的任何实例化,以及嵌套unordered_map
s的任何深度。
这是一个演示。
另外,如果您没有c ++ 17,则可以if constexpr
使用带有单个KeyType
参数的重载模板重写解决方案。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句