使用std :: array的代码大小

时间:2015-04-04 21:20:21

标签: c++ c++11 embedded

我正在使用嵌入式系统(ARM Cortex-M0,所以没有Linux)。我为嵌入式平台编写了很多C代码,但这是我第一次涉足C ++。

在我的C代码中,传递给函数的数组总是占用2个参数。一个用于指向数据的指针,另一个用于指向数组的长度。例如:

void write(uint8_t *buf, size_t bufLen, size_t writeLen);

我考虑将这些转换为使用std::array(在C ++ 11中引入)。它很有吸引力,因为它跟踪自己的长度,但没有做任何分配。它看起来像是等价的

template<size_t N> void write(array<uint8_t, N> *buf, size_t writeLen);

如果我的代码最终用10个不同大小的数组调用write,那么编译器最终会定义10个不同的函数吗?如果我定义一个需要两个(或更多)数组的函数,这似乎特别糟糕,因为函数必须在2个参数(每个数组的大小)上进行模板化:

template<size_t N, size_t M>
void readWrite(array<uint8_t, N> *readBuf,
               array<uint8_t, M> *writeBuf, size_t writeLen);

3 个答案:

答案 0 :(得分:2)

如果write()代码在编译时不了解bufLen,那么我认为没有任何改变它的意义。我将保留原始函数原型并按需添加便利包装器,如下所示:

template<size_t N>
void write(array<uint8_t, N> &buf, size_t count) {
    write(buf.data(), buf.size(), count);
}

您可以为不同的缓冲区类型添加更多内容,例如vectorstring。在优化的构建中,所有这些包装器都是微不足道的内联,因此没有代码重复,尽管在编译之后它仍然值得检查。

下一步是使用尚未标准的array_view。但是你可以从某个地方借用实现或者轻松地创建自己的实现。有了它,您可以将主函数定义为

void write(array_view<uint8_t>, size_t);

你甚至不需要任何包装器,因为array_view可以从C数组和各种容器中隐式构造。

答案 1 :(得分:1)

理论上,是的。但是,模板函数必须在使用它的TU中定义。这意味着它很容易内联。

不过,还要看看std::vector

答案 2 :(得分:0)

只要您传递的内容实际上是数组(不是指针),您可以通过将函数重写为模板来完成大致相同的操作,但是将引用传递给原始数组而不是{{1} }。这给了我们这样的代码:

std::array

因此,我们可以这样做:

template <size_t N>
void write(uint8_t (&buf)[N]);

...在第一次调用中,编译器会将uint8_t buffer[256]; write(buffer); uint8_t buffer2[512]; write(buffer2); 推导为256,而在第二次调用中则为512.

基本效果是相同的 - 至少可能,编译器仍会为您传递的每个数组大小生成唯一代码。