首页 > 解决方案 > 使用元编程的结构初始化/构造函数

问题描述

为了实现Block floating point,我在我的代码中使用了以下结构:

struct ff32{
    int16_t _exp;
    int32_t _frac;

    ff32(int16_t e, int32_t f)
        : _exp(e), _frac(f)
    {};
};

我可以实例化这种结构类型的变量并将它们初始化如下:

ff32 x(2, 0x60000000);
ff32 y = {2, 0x60000000};

我想扩展构造函数以包含浮点数据类型,如下所示:

struct ff32{
    int16_t _exp;
    int32_t _frac;

    ff32(int16_t e, int32_t f)
        : _exp(e), _frac(f)
    {};

    ff32(float x)
    {
        // some code that extract _exp and _frac 
        // for a given floating-point number x
    };
};

我已经实现了构造函数 ff32(float x) 的主体,但我不希望在运行时为常量浮点参数执行此代码,例如 ff32(2.7f)。是否可以使用某种元编程来实现这一点?我还应该提到我的工具链只支持 C++11。

标签: c++c++11structconstructormetaprogramming

解决方案


这里不需要元编程。

在任何情况下都会创建该函数ff32(float x),但正如 Klaus 所提到的,您可以依靠编译器优化来用相应的值替换它在 constexpr 浮点数上的结果,而无需在运行时调用该函数。只需使用以下计算(可以在编译时执行):

struct float32{
    unsigned const bits;
    unsigned const exponent;
    unsigned const fraction;
    bool const sign;

    constexpr float32(float input_float):
        bits(*reinterpret_cast<unsigned*>(&input_float)),
        exponent((bits & 0x7f800000) >> 23),
        fraction((bits & 0x007fffff)),
        sign((bits & 0x80000000) > 0)
    {}
};

您可以在此处观看您的代码编译到的程序集。确保使用 -O3 标志,看看它是如何在 constexpr 浮点数上工作的。


推荐阅读