c++ - 我应该如何将一个值插入另一个的 "middle"?

标签 c++ arrays c++11 byte idioms

我有两个值 v1 和 v2,分别是 T1 和 T2 类型,sizeof(T1)>sizeof(T2)。两种类型都是普通旧数据。现在,我想用 v2 的字节替换 v1 的第 k、k+1、... k+sizeof(T2)-1 个字节。

C++ 本身并没有在语言中提供这种功能,据我所知在标准库中也没有(至少,没有直接提供)。一般实现此方法的最佳方法是什么?即实现:

template<typename T1, typename T2>
void replace_bytes(T1& v1, T2 v2, std::size_t k)

或至少

template<typename T1, typename T2, std::size_t k>
void replace_bytes(T1& v1, T2 v2)

?

我的想法是:

  1. 重新解释转换为字节数组
  2. 重新解释为 std::array of bytes
  3. 使用跨度
  4. 用v1的地址进行指针运算
  5. 对于不太大的类型 - 重新解释为无符号整数并使用位运算:AND 与掩码、移位或 OR 组合现有位和替换位。

注意事项:

  • 当然,如果 k 太高,这里就会有 UB(或者我们可以检查它不是太高)。
  • 为了简单起见,您可以假设内存布局是小端。
  • 如果一致性是一个问题,请明确说明您的选择。
  • 效率/速度当然是一个关键问题。
  • 如果您的建议需要更新的 C++ 语言标准,那很好,但请务必提及。
  • 在编译期间对代码进行良好优化很重要。

最佳答案

// needed include files
#include <iostream>  // for cout
#include <stdexcept> // for runtime_error
#include <cstring>   // for memcpy

// generic template function that takes 3 arguments
// 1 destination object
// 2 source object
// 3 from which byte to start in the destination
template<class T1, class T2>
void replace_bytes ( T1& t1, const T2& t2, std::size_t k )
{
// at compile time, store the size of T1 type in t1_size
   constexpr std::size_t t1_size = sizeof(T1);
// at compile time, store the size of T2 type in t2_size
   constexpr std::size_t t2_size = sizeof(T2);
// if we copy t2 bytes to t1, do we run out of memory ?
   if ( k + t2_size > t1_size )
   {
       throw std::runtime_error("Can't copy out of bounds.");
   }
// do the copying, casting is required for proper pointer arithmitic
   std::memcpy( (void*) (((char*)&t1)+k), (const void*) &t2, t2_size );
}

int main()
{
  int x = 0;
  char c = 10;
  replace_bytes(x, c, 0);
  std::cout << x << std::endl;
}

代码的干净版本(无注释):

#include <iostream>
#include <stdexcept>
#include <cstring>

template <class T1, class T2>
void replace_bytes ( T1& t1, const T2& t2, std::size_t k )
{
   constexpr std::size_t t1_size = sizeof(T1);
   constexpr std::size_t t2_size = sizeof(T2);

   if ( k + t2_size > t1_size )
   {
       throw std::runtime_error("Can't copy out of bounds.");
   }
   std::memcpy( (void*) (((char*)&t1)+k), (const void*) &t2, t2_size );
}

int main()
{
  int x = 0;
  char c = 10;
  replace_bytes(x, c, 0);
  std::cout << x << std::endl;
}

关于c++ - 我应该如何将一个值插入另一个的 "middle"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55888672/

相关文章:

c++ - 如何将指针传递给构造函数?

Java ArrayList 内容不传播

c# - 绑定(bind)到最后一个数组元素

c++ - C++ 标准库中的哪些头文件保证包含另一个头文件?

c++ - 线程多次调用析构函数

c++ - 查看 C++ new[] cookie。这段代码的可移植性如何?

c++11 - 如何在构造 std::vector 时放置元素?

c++ - 为什么没有默认的 move 分配/move 构造函数?

c++ - 类模板参数推导不适用于别名模板

java - 我如何删除java中的数组条目(请简单一点?)