我一直在努力想出这个,并且认为看一下它会很有趣:)
好的,所以我正在使用位域创建一个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的新手,所以请帮助我们!
答案 0 :(得分:0)
reinterpret_cast
与static_assert
不兼容,即使其行为定义明确,但您的使用具有特定于实现的行为。允许编译器拒绝这样的代码,或者如果执行这样的转换,机器将被允许崩溃和刻录。
要使其发挥作用,请将constexpr operator uint64_t () const
添加到PointerData
,这会返回您期望reinterpret_cast
产生的值。然后将reinterpret_cast
更改为static_cast
。
编辑:不,C ++不支持您尝试的内容。常量表达式求值(如constexpr
中所示)要求编译器在一定程度上模拟目标平台。此模拟器需要将未定义的行为标记为错误,以及许多特定于实现的情况,包括所有reinterpret_cast
表达式。
reinterpret_cast
的体系结构不起作用,因为它在模拟器中执行其内省。您需要将其移动到构建系统&#34; canary&#34;或者改为启动程序。