查找自动生成键并具有线性内存消耗的小型关联数组
looking for small associated array where key is automatic generated and has linear memory consumption
就像标题所说,我正在寻找一个具有线性内存消耗的关联数组(如地图((如 std::vector(,其中键是为新条目自动生成的。N <128。
例如,我们可以将其用于观察者模式,如果您可以将回调注册到值更改事件。作为回报,您将获得一个 id(整数(。使用此 ID,您可以稍后取消注册回调。
别名代码:
/// Registers a callback and returns an associated id to it.
int register_callback(std::function callback);
/// Returns true if callback was unregistered for given id.
bool unregister_callback(int id);
由于这应该在有内存限制的嵌入式设备中使用,所以我不会使用映射作为容器(请参阅此处:http://jsteemann.github.io/blog/2016/06/14/how-much-memory-does-an-stl-container-use/,映射使用的内存是矢量的 ~5 倍(。
我有一些想法如何自己实现这一点,但我想知道是否已经存在任何名称/概念?
这将是我的想法:
template<typename T>
class custom_map { // Totally unsure with naming
// coll_ is sorted.
std::vector<std::pair<uint8_t, T>> coll_;
public:
uint8_t add(T) {
// Find unused id by iterating over coll_,
// If ((prev id + 1) != (next id)), free id found.
// Insert into coll new pair and sort.
}
bool remove(uint8_t id) {
// Remove element in coll with associated id
// Binary search would be faster but only for bigger sizes, so linear search?
}
// Iterator concept begin/end... to iterate over collection.
};
您不需要在对象中保存单独的 id。您可以使用向量的索引作为 id。那会快得多。
template<typename T>
class custom_map { // Totally unsure with naming
std::vector<T*> coll_;
public:
uint8_t add(T*obj) {
// Find unused id by iterating over coll_,
for (int i = 0; i < coll_.size(); ++i) {
if (coll_[i] == nullptr) {
coll_[i] = obj;
return i;
}
}
coll_.push_back(obj);
return coll_.size() - 1;
}
bool remove(uint8_t id) {
coll_[id] = nullptr;
}
// Iterator concept begin/end... to iterate over collection.
};
您可能使问题过于复杂,您可以简单地使用向量的索引作为键:
#include <vector>
#include <cstdint>
#include <functional>
#include <iostream>
template<typename T>
class custom_map {
std::vector<T> coll_;
public:
size_t add(const T& t) {
for (auto it = coll_.begin(); it != coll_.end(); ++it)
{
if (!(*it))
{
*it = t;
return it - coll_.begin();
}
}
coll_.push_back(t);
return coll_.size() - 1;
}
bool remove(size_t id) {
if (id >= coll_.size() || !coll_[id]) {
return false;
}
coll_[id] = {};
// remove empty elements from the end of the list
if (id == coll_.size()-1) {
auto toRemove = std::count_if(coll_.rbegin(), coll_.rend(), [](const T& t) { return !t; });
coll_.resize(coll_.size() - toRemove);
}
return true;
}
};
int main()
{
custom_map<std::function<void()>> map;
auto i = map.add([](){std::cout << "1n"; });
map.remove(i);
}
这仅适用于默认初始化为可转换为 false 的值的类型(如std::function
(,对于其他类型,您只需将类型包装在std::optional
中,例如(映射实际上也适用于int
,但0
空值可能不是您想要的(:
int main()
{
custom_map<std::optional<int>> map;
auto i = map.add(10);
map.remove(i);
}
相关文章:
- Mongodb c++驱动程序:如何查询元素的数组
- 将数组的地址分配给变量并删除
- 从C++本机插件更新Vector3数组
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 数组索引的值没有增加
- 将对象数组的引用传递给函数
- 为char数组调整zlib-zpipe
- 2D数组来自文本输入,中间有空格
- std::向量与传递值的动态数组
- 在c++中用vector填充一个简单的动态数组
- 使用strcpy将char数组的元素复制到另一个数组
- 使用指针从C++中的数组中获取最大值
- C++使用整数的压缩数组初始化对象
- 告诉一个 const char 数组,除了编译时 C 样式的字符串外,它不以 '