如何在保持constexpr的同时访问constexpr创建的类型作为另一种类型? (与static_assert一起使用)

时间:2014-07-12 01:16:07

标签: c++ c++11 constexpr bit-fields static-assert

我一直在努力想出这个,并且认为看一下它会很有趣:)

好的,所以我正在使用位域创建一个constexpr类型。由于位域可以从一个实现或平台变为另一个,我想static_assert这些位在正确的位置。和我一起到目前为止?这是我正在创建的类型的代码:

// Currently hard-coded for 64bit, will change later when I get past this part...
constexpr int getPointerBitCount()          { return 64; }
constexpr int getPointerByteWidth()         { return getPointerBitCount() / 8; }
constexpr int getPointerDataWidth()         { return 3; }
constexpr int getPointerPointerWidth()      { return getPointerBitCount() - getPointerDataWidth(); }
struct PointerData
{
    bool _invalid       :1;
    bool _delete        :1;
    bool _unused        :1;
    uint64_t _pointer   :getPointerPointerWidth();

    constexpr PointerData(bool invalid, bool isDelete, bool unused)
        : _invalid{invalid}
        , _delete{isDelete}
        , _unused{unused}
        , _pointer{0}
    {
    }
};

所以现在我想做的是:

static_assert(reinterpret_cast<uint64_t>(PointerData(true, false, false)) == 1, "PointerData not supported on this platform");
static_assert(reinterpret_cast<uint64_t>(PointerData(false, true, false)) == 2, "PointerData not supported on this platform");
static_assert(reinterpret_cast<uint64_t>(PointerData(false, false, true)) == 4, "PointerData not supported on this platform");

基本上,我需要创建PointerData类型作为constexpr,然后对它运行测试,好像整个事情是uint64_t(或32位的uint32_t)。但是,我的编译器说我不能在这里使用reinterpret_cast。关于如何做到这一点的想法?

运行按位运算符来计算值将无法实现我正在寻找的东西。我需要“按原样”访问变量。这里的测试是查看位域中的第一位是否等于1.(第二位= 2,第三位= 4)。

我考虑过创建一个联盟,但我不确定这是否适合给定位域。不确定。

我是constexpr的新手,所以请帮助我们!

1 个答案:

答案 0 :(得分:0)

reinterpret_caststatic_assert不兼容,即使其行为定义明确,但您的使用具有特定于实现的行为。允许编译器拒绝这样的代码,或者如果执行这样的转换,机器将被允许崩溃和刻录。

要使其发挥作用,请将constexpr operator uint64_t () const添加到PointerData,这会返回您期望reinterpret_cast产生的值。然后将reinterpret_cast更改为static_cast

编辑:不,C ++不支持您尝试的内容。常量表达式求值(如constexpr中所示)要求编译器在一定程度上模拟目标平台。此模拟器需要将未定义的行为标记为错误,以及许多特定于实现的情况,包括所有reinterpret_cast表达式。

reinterpret_cast的体系结构不起作用,因为它在模拟器中执行其内省。您需要将其移动到构建系统&#34; canary&#34;或者改为启动程序。