consteval中的强制转换指针



我想做一个compiletime数据加密器
我尝试过创建一个带有缓冲区的结构,并为该结构创建一个构造函数,
将读取该缓冲区中的结构数组。因为我想使用blockcypher,所以
我希望缓冲区长度可以被16设计。

这是我的代码库:

template <typename type, size_t len>
struct DataPackage
{
unsigned char buffer[len * sizeof(type) + (16 - ((len * sizeof(type)) % 16))]; //create buffer to fit all types and fill to 16 byte blocks
__forceinline consteval DataPackage(type data[len])
{
for (int i = 0; i < sizeof(buffer); i++)
buffer[i] = i < len * sizeof(type) ? *(reinterpret_cast<unsigned char*>(data) + i) : '';

//encrypt buffer here
}
};

它给出了一个错误:
从"type*"到"unsignedchar*"的对话在常量表达式求值中无效。

我使用visual c++编译器和c++20。

有没有一种方法可以在consteval函数中将指针强制转换为指向不同类型的指针?是否有一个肮脏的编译破解解决方案?究竟是什么阻止了我这样做,这在未来的c++版本中可以修复吗?

在常量表达式中不可能将数据重新解释为不同的类型,但如果您的意图是将对象表示强制转换为不同类型:

auto obj_repr = std::bit_cast<std::array<unsigned char, sizeof(type)>>(data[i]);

现在obj_reprunsigned char的数组,包含该数组的第i个元素的对象表示。你可以对那个副本进行操作。

这当然要求T是可复制的。否则,reinterpret_cast方法无论如何也会有未定义的行为。此外,为了使其作为常量表达式工作,type可能不是或包含指针类型、并集类型、指向成员类型的指针、volatile限定类型或引用类型作为子对象。

(理论上是否总是保证这一点存在一些分歧,因为std::array可能不需要没有填充,但在实践中它会起作用。例如,请参阅std::bit_cast with std::array(


consteval函数在编译时只能求值。因此,我非常怀疑__forceinline对它有任何意义,尽管这当然是纯粹的实现定义,我不知道MSVC在这种情况下如何处理它。

通常consteval不需要constexpr。我在您显示的代码中没有看到任何需要防止在运行时进行评估的内容。

最新更新