将模板限制为所有调用所需的最大数据类型

Restrict template to largest data type necessary for all calls

我有一些计算数字运算的函数:

int32_t compute(int32_t x) {
    // just a placeholder; the details don't matter
    return ~x;
}

full函数有点大,还拉入了其他大数函数。我想保存每个字节,因为它适用于带有微型 ROM 的 8 位微控制器。

一般我想至少支持32位输入,所以我用了int32_t,但在大多数构建中,不会调用更多比 16 位甚至 8 位输入,所以硬编码类型总是这么大通常是一种浪费。

我可以使用模板类型:

template <typename T>
T compute(T x) {
    return ~x;
}

现在,如果仅用于 8 位类型,则所有 32 位内容都会消失。

但是当在特定构建中使用 多个 类型调用它时,事情会变得更糟,因为现在该函数有多个副本。当 int32_t 版本可以满足所有用途时,我不需要 int32_t、int16_t、int8_t 的单独专业化。 (我不担心速度,只担心大小。)

所以我只想要一个版本的函数,但使用可以满足应用程序中所有用途的类型。

是否有任何模板、宏、编译器扩展、链接器魔术等可以解决这个问题?


更新:如果我将问题限制在单个翻译单元,是否会开辟任何新方法?

没有,至少没有你要求的那么灵活。问题是,全球使用最广泛的类型要到 link 时间才能知道……但到那时再用弱符号做任何巧妙的事情都为时已晚,因为编译后的调用代码已经期望调用特定的整数类型。换句话说,目标宽度需要在每个翻译单元中都是已知的,但可能会受到其他翻译单元的影响。

有一个可配置的宏或 typedef 来确定使用的宽度,并打开编译器警告以缩小整数以捕获设置不正确的情况。

跨构建管理类型的大小是一个 compile-time 问题。给自己设置一个#define 来修复它。

我不建议您重新定义任何现有的整数类型。创建您自己的整数类型,并在编译时声明。

例如:

integer compute(integer t) {
  ...
}

并且在编译命令中:

-Dinteger=int32_t

或:

-Dinteger=int16_t

等等

-D command-line 标志等同于代码中某处的 #define integer int32_t 等。如果您正在使用某种构建系统,请将其设置为 integer(或您称之为数字类型的任何内容)需要在构建标志中定义。