如何从 constexpr 表达式中的 const void* 进行转换?
How to cast from const void* in a constexpr expression?
我正在尝试将 memchr 重新实现为 constexpr (1)。我没有预料到问题,因为我已经用非常相似的 strchr 成功地完成了同样的事情。
但是 clang 和 gcc 都拒绝将 const void* 强制转换为 constexpr 函数中的任何其他内容,这使我无法访问实际值。
我知道在 constexpr 函数中使用 void* 很奇怪,因为我们不能执行 malloc 并且无法将任意数据指定为文字值。我这样做基本上是作为练习的一部分,尽可能多地重写 as constexpr (2)。
我仍然想知道为什么不允许这样做,以及是否有任何解决方法。
谢谢!
(1) 我的memchr实现:
constexpr void const *memchr(const void *ptr, int ch, size_t count) {
const auto block_address = static_cast<const uint8_t *>(ptr);
const auto needle = static_cast<uint8_t>(ch);
for (uintptr_t pos{0}; pos < count; ++pos) {
auto byte_address = block_address + pos;
const uint8_t value = *byte_address;
if (needle == value) {
return static_cast<void const *>(byte_address);
}
}
return nullptr;
}
(2) Github 上的整个项目:https://github.com/jlanik/constexprstring
不,不可能在常量表达式中以这种方式使用void*
。在常量表达式中禁止从 void*
转换为其他对象指针类型。 reinterpret_cast
也被禁止。
这可能是故意的,以便在编译时无法访问对象表示。
您不能在编译时使用具有通常签名的 memchr
。
我认为你能做的最好的事情是编写指向 char
及其 cv 限定版本的指针的函数,以及 std::byte
(作为重载或模板),而不是void*
.
对于指向其他类型对象的指针,在某些情况下会很棘手,在大多数情况下不可能实现 memchr
.
的确切语义。
虽然我不确定这是否可能,但也许,在 memchr
的模板化版本中,可以通过 std::bit_cast
读取指针传递的对象的底层字节到包含适当大小的 std::byte
/unsigned char
数组的结构。
我正在尝试将 memchr 重新实现为 constexpr (1)。我没有预料到问题,因为我已经用非常相似的 strchr 成功地完成了同样的事情。
但是 clang 和 gcc 都拒绝将 const void* 强制转换为 constexpr 函数中的任何其他内容,这使我无法访问实际值。
我知道在 constexpr 函数中使用 void* 很奇怪,因为我们不能执行 malloc 并且无法将任意数据指定为文字值。我这样做基本上是作为练习的一部分,尽可能多地重写 as constexpr (2)。
我仍然想知道为什么不允许这样做,以及是否有任何解决方法。
谢谢!
(1) 我的memchr实现:
constexpr void const *memchr(const void *ptr, int ch, size_t count) {
const auto block_address = static_cast<const uint8_t *>(ptr);
const auto needle = static_cast<uint8_t>(ch);
for (uintptr_t pos{0}; pos < count; ++pos) {
auto byte_address = block_address + pos;
const uint8_t value = *byte_address;
if (needle == value) {
return static_cast<void const *>(byte_address);
}
}
return nullptr;
}
(2) Github 上的整个项目:https://github.com/jlanik/constexprstring
不,不可能在常量表达式中以这种方式使用void*
。在常量表达式中禁止从 void*
转换为其他对象指针类型。 reinterpret_cast
也被禁止。
这可能是故意的,以便在编译时无法访问对象表示。
您不能在编译时使用具有通常签名的 memchr
。
我认为你能做的最好的事情是编写指向 char
及其 cv 限定版本的指针的函数,以及 std::byte
(作为重载或模板),而不是void*
.
对于指向其他类型对象的指针,在某些情况下会很棘手,在大多数情况下不可能实现 memchr
.
虽然我不确定这是否可能,但也许,在 memchr
的模板化版本中,可以通过 std::bit_cast
读取指针传递的对象的底层字节到包含适当大小的 std::byte
/unsigned char
数组的结构。