【问题标题】:How do i reinterpter_cast vector to int?我如何将向量重新解释为 int?
【发布时间】:2020-05-30 20:06:41
【问题描述】:

我有一个四个字节的向量: std::vector<int8_t> src = { 0x0, 0x0, 0x0, 0xa };,十六进制是。 (0x0000000a)

我如何将它输入到int32_t,以便使用reinterpret_cast 得到10?

这可以使用如下的位移轻松完成:

(int32_t)((src[offset] << 24) | (src[offset+ 1] << 16) | (src[offset+ 2] << 8) | (src[offset+ 3]));

但就我所知reinterpret_cast 的工作方式而言,它可以在这里发挥最佳作用,但我无法弄清楚代码本身是如何做到这一点的。

reinterpret_cast<int32_t*>(&0x0000000a);

ps:这不仅适用于 int32_t 左右,还可以重新解释为我想要的任何东西。这就是重点。

【问题讨论】:

  • 取决于你的字节序,我猜。计算路线被视为禁区的任何原因?
  • @paxdiablo 大端,x64。我是在java中做到的,据我所知,它没有类型双关语机制。我猜我本可以在 C++ 中使用 reinterpret_cast 更轻松地做到这一点,但小伙子还没有弄清楚。
  • 请注意,您实际上可以做到这一点的是 Java 使用 ByteBuffer - ByteBuffer.wrap(new byte [] { 0x0, 0x0, 0x27, 0x10 }).asIntBuffer().get()
  • @greg-449 是的,我知道。问题是,我需要使用不安全的方法以我想要的方式“处理”字节。 reinterpret_cast 是使用 C++ 的方式,我很确定。但我无法弄清楚如何做到这一点的确切方法。我有字节流,我想将它们从向量重新解释为我想要的任何类型。
  • 你试过int32_t value = *(reinterpret_cast&lt;int32_t*&gt;(src.data()));吗?

标签: c++ casting reinterpret-cast


【解决方案1】:
#include <iostream>
#include <numeric>
#include <vector>

int main() {
  std::vector<int8_t> src = { 0x0, 0x0, 0x27, 0x10 };
  std::cout <<
    std::accumulate(src.begin(), src.end(),  // or src.begin() + sizeof(int32_t)
       0, [](const uint32_t &a, const uint8_t &b){ return a * 256 + b; });
  std::cout << std::endl;
  return 0;
}

【讨论】:

  • 如果任何 int8_t 值为负数,这将不起作用
  • @MM 谢谢。修好了。
【解决方案2】:

这是不可能的;由于严格的别名违规,尝试将是未定义的行为。 int8_t 的数组不能作为其他类型访问(规则中列出的这种特定情况除外,例如 uint8_t)。

使用 bitshifts 或 memcpy 是正确的方法(就像 S.M. 的回答的想法)

【讨论】:

  • 我认为 reinterpret_cast 等功能的全部意义在于让程序员自行承担对任何特定情况的控制权。我知道这些位。我只是想以我想要的方式重新解释它们。如果我的理解是正确的,向量元素会像 int32_t 一样存放在内存中。
  • @Richard 无论演员阵容如何,严格的别名规则仍然适用。您也许可以使用编译器扩展(例如,将-fno-strict-aliasing 提供给 gcc)
  • 我在 MSVC 上,所以我猜我们会放手的。说到memcpy。它给出了与 reinterpret_cast 相同的结果。显然,输入双关语的唯一方法是对位集(C++20)进行位移。
猜你喜欢
  • 2013-01-15
  • 1970-01-01
  • 1970-01-01
  • 2020-03-15
  • 2019-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多