在编译时将积分和分数部分宏组合为新宏或双精度宏

时间:2019-06-20 20:43:32

标签: c++ preprocessor

我在两个预处理器定义中都有主版本号和次版本号

#define i 123
#define f 4567

,并且需要提供一个函数,将它们作为一个双精度值组合起来返回,其中主数是整数,而小数是小数部分。

除了重复这些数字外,我能想出的所有解决方案都具有很强的表现力。在这里看到例如: https://godbolt.org/z/rg3GyR

没有constexpr,它将表现得更好,但也可以做到。

在MS世界中,我逃脱了

  #define me i.f
  double df() { return me; }

但是Standard C ++不能提供这种可能性。

我想知道是否存在一种简单的符合标准的方法。

1 个答案:

答案 0 :(得分:4)

@NathanOliver关于将事物存储为double的精度的评论很重要。但是,如果您想通过将内容存储为显式double进行操作,则可以使用令牌粘贴运算符和某些级别的宏间接将所有内容显式粘合在一起:

#define MAJOR 123
#define MINOR 4567

/* Two macro levels are necessary here so that the arguments MAJOR
 * and MINOR get expanded out to their true values.
 */
#define GLUE2(a, b) a##.##b
#define GLUE(a, b) GLUE2(a, b)

/* Now, VERSION is the constant 123.4567. Or at least, the closest
 * approximation of that value using a double.
 */
#define VERSION GLUE(MAJOR, MINOR)

其他可能更适合您的选项:

  1. 创建一个struct来代表您的版本,并使其明确存储主要和次要版本字段。这是编码想法的最“诚实”的方式。

  2. 将版本打包为一个无符号整数(可能是32位或64位),其中整数的上半部分是主要版本,下半部分是次要版本。这样,您可以使用正整数运算来比较版本,还可以执行一些愚蠢的事情,例如将版本相乘,按版本进行修改等。

  3. 对所有内容使用字符串。这样,您可以存储任何长度和任何描述级别的版本。