容器模板形参std::map或std::vector
Container template parameter std::map or std::vector
在我的一个项目中,我使用了一个树实现,在那里我使用了容器C=std::map<K,V>
维护每个树节点的子节点列表。每个树节点有一个唯一的名称键K
通常是std::string
。
template<typename V, template<typename Key=std::string,typename Type=TreeNode<V>,typename ...> typename C>
class TreeNode {
typedef C<std::string, Value> cont_type;
typedef V data_type;
cont_type childs;
data_type value;
cont_type::iterator genericFind(const K& k) {
// Something generic here!!!
}
}
这个实现对我来说工作得很好,除了std::map不尊重树中插入的顺序。对于某些应用程序,我需要保持插入的顺序,但对于其他应用程序,快速检索信息的需求更为重要。
因此C
需要是类型
std::vector<std::pair<K, V>> // keeping insertion order
或
std::map<K,V> // fast information retrivial
不,我对TreeNode
类的实现有问题,仍然显式使用std::map
的接口。特别是,它使用的成员函数find
、erase
、insert
需要用泛型替换,这两种容器类型的实现都是相当具体的。
例如childs.find(key)
需要替换为find(childs.begin(), childs.end(), key)
,每当我插件std::vector
的实现。
也许有另一个解决方案,我不知道。这可能是boost::multi_index
,但我对此很不确定。
解决我的问题最简单的方法是什么?
您可以创建专用的重载函数,并使用它们
template <typename Key, typename V>
auto my_find(std::map<Key, V>& m, const Key& key)
{
return m.find(key);
}
template <typename Key, typename V>
auto my_find(std::vector<std::pair<Key, V>>& v, const Key& key)
{
return std::find_if(v.begin(), v.end(), [&](const auto& p) {
return p.first == key;
});
}
用相同的接口为您想要的容器"choices"创建通用包装器:
template <typename TKey, typename TValue>
class my_map_wrapper
{
private:
std::map<TKey, TValue> _map;
public:
// Same interface as 'my_vector_wrapper'.
template <typename TEKey, typename TEValue>
void emplace(TEKey&& key, TEValue&& value)
{
_map.emplace(std::make_pair(std::forward<TEKey>(key),
std::forward<TEValue>(value)));
}
// ...
};
template <typename TKey, typename TValue>
class my_vector_wrapper
{
private:
std::vector<std::pair<TKey, TValue>> _vec;
public:
// Same interface as 'my_map_wrapper'.
template <typename TEKey, typename TEValue>
void emplace(TEKey&& key, TEValue&& value)
{
_vec.emplace_back(std::forward<TEKey>(key),
std::forward<TEValue>(value));
}
// ...
};
在包装器本身上模板化树节点类:
template <typename TWrapper>
class TreeNode
{
private:
TWrapper _container;
public:
// Use "uniform" container interface...
};
现在可以在用户代码中定义方便的类型别名来选择不同的容器:
template <typename TKey, typename TValue>
using MapTreeNode = TreeNode<my_map_wrapper<TKey, TValue>>;
template <typename TKey, typename TValue>
using VectorTreeNode = TreeNode<my_vector_wrapper<TKey, TValue>>;
相关文章:
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- 使用一个考虑到std::map中键值的滚动或换行的键
- 有没有办法对std::unordered_set、std::unrdered_map、std::set、std::map
- 将重物插入std::map
- 使用通用值初始化 std::map,不重复
- 仅包含可移动 std::map 的类的移动构造函数不起作用
- C++:当所有条目都保证是唯一时,替代 std::map
- 使用模板化的键类型定义 std::map,该键类型基于作为参数接收的函数
- 如果 KEY 是 std::list 或 std::vector 而不是值,那么 std::map 的默认行为是什么?
- C++如何创建 std::map
- 从其他容器中移动构造"std::map"
- 将 std::map::emplace 与返回 shared_ptr 的函数一起使用是否正确?
- C++中 std::map 的运行时复杂度是多少?
- 为什么在 std::map 上移动无法将元素从一个映射移动到另一个映射
- 使用重载 [] 运算符返回 std::map() 的可赋值
- std::map, std::unordered_map - 缩小初始值设定项列表中的转换范围
- C++ 使用枚举类对象分配 std::map 值
- 静态 std::map instatiation 在类的方法中调用构造函数吗?
- std::map:当元素不可默认构造时创建/替换元素
- Arduino编译器和STL:使用std::vector和std::map