我为我的嵌入式 MCU 项目做了一个非常简单的池分配器。它是一个模板类,具有以下接口(跳过实现部分,如果有人感兴趣,我也可以发布它):
template <typename T, size_t size>
class SimplePoolAllocator
{
public:
SimplePoolAllocator();
T * allocate();
void deallocate(T *pointer);
...
}
它非常适用于类或 POD 等“简单”事物,例如:
SimplePoolAllocator<double, 10> poolOfDouble; // returns "double *"
SimplePoolAllocator<WeirdClass, 5> poolOfObjects; // returns "WeirdClass *"
如果我想将它用于固定大小的数组,就会出现问题。这种用途当然是用于原始数据缓冲区——在我的项目中,我有两种“传输”类型,一种有 16 个字节,另一种有 100 个。
所以假设我这样使用:
SimplePoolAllocator<uint8_t[16], 10> pool1;
SimplePoolAllocator<uint8_t[100], 10> pool2;
一切似乎都很好,但问题是现在 allocate() 返回这样的东西:“uint8_t(*)[16]”和“uint8_t(*)[100]”。理想情况下,我希望它只返回“uint8_t *”(指向开始的指针)。
我知道我可以这样做:
uint8_t *p = *pool1.allocate(); // additional asterisk to "drop" the array thing from the type
但这看起来……很奇怪……
所以问题是 - 我如何改进我的 SimplePoolAllocator 的接口(或任何东西)以支持“普通”对象(如上所示 - 类和 POD)和固定大小数组的简单分配,但只返回指向第一个元素的指针?是否可以在不使用 std::array 和使用它的 data() 成员函数的情况下完成,或者在整个地方不使用额外的“*”?C ++ 11 功能对我来说没问题,如果有某种东西可以“转换”这样的类型,它可以在这里救我:WeirdClass -> WeirdClass *,uint8_t[16] -> uint8_t *。我不能轻易地将缓冲区包装在类中,因为我以“原始”形式处理中断中的传输 - 我需要的只是指向缓冲区的指针,该指针稍后通过消息队列传递给任务进行处理,带有“类型” (大小) 作为消息的元素之一。如果可能的话,我想避免在这个简单的任务中使用虚函数 (;
可以做到吗,还是我要求太多了?也许唯一的解决方案是使模板的接口像这样:
template <typename T, size_t array_size, size_t size>
所以我有:
SimplePoolAllocator<WeirdClass, 1, 10> pool1;
SimplePoolAllocator<uint8_t, 16, 10> pool2;
但这看起来也不是很好……
提前谢谢任何建议!请注意,这个问题是关于微控制器的项目,所以使用 Boost 或类似的东西是不可能的。