如何将值插入“中间”字段?另一个? [英] How should I insert a value into the "middle" of another?

查看:98
本文介绍了如何将值插入“中间”字段?另一个?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have two values v1 and v2 of types T1 and T2 respectively, with sizeof(T1)>sizeof(T2). Both types are plain-old-data. Now, I want to replace the k'th, k+1'th, ... k+sizeof(T2)-1'th bytes of v1 with the bytes of v2.

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

C++ doesn't offer this functionality inherently in the language, nor to my knowledge in the standard library (at least, not directly). What would be the best approach to implementing this generically? i.e. implementing:

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 :: bytes的数组

  3. 使用跨度

  4. 地址为v1的指针算术

  5. 对于不太大的类型-重新解释为无符号整数并使用位运算:与掩码,移位或进行或运算以组合现有位和替换位。

  1. Reinterpret cast into arrays of bytes
  2. Reinterpret cast into std::array of bytes
  3. Use spans
  4. Pointer arithmetic with the address of v1
  5. For not-so-large types - reinterpret as unsigned integers and use bit operations: AND with a mask, shift, OR to combine the existing and replacement bits.

注意:


  • 当然,如果 k 太高了,这里会有UB(或者我们可以检查它是否太高了。)。

  • 为简单起见,您可能会认为内存布局是小端的。 / li>
  • 如果对齐是一个问题,请明确说明您的选择。

  • 效率/速度当然是关键问题。

  • 如果您的建议需要更新的C ++语言标准,那很好,但是请务必提及。

  • 在编译期间对代码进行优化是很重要的。

  • Of course if k is too high there will be UB here (or we could check it isn't too high).
  • You may assume for the sake of simplicity that memory layout is little-endian.
  • If alignment is an issue, be explicit about your choices regarding it.
  • Efficiency/speed is of course a key issue.
  • If your suggestion requires a newer C++ language standard, that's fine, but do mention it.
  • It is important for the code be well-optimized during compilation.

推荐答案

// 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;
}

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

Clean version of code (no comments):

#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;
}

这篇关于如何将值插入“中间”字段?另一个?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆