如何将几个变量复制到其他变量
How to copy few variables to other variable?
例如,
struct Foo
{
Foo(uint8_t b0, uint8_t b1, uint16_t b23)
{
// some code here
}
uint32_t m_n;
};
我可以写这样的东西:
auto dest = reinterpret_cast<uint8_t*>(&m_n);
memcpy(dest, &b0, sizeof(b0));
memcpy(dest + sizeof(b0), &b1, sizeof(b1));
memcpy(dest + sizeof(b0) + sizeof(b1), &b23, sizeof(b23));
但它非常丑陋。当有15个这样的变量时该怎么办(不要问为什么(
我怀疑您需要这种函数:
template<typename T>
std::enable_if_t<std::is_integral_v<T>, std::array<uint8_t, sizeof(T)>>
littleEndianBytes(T value)
{
static_assert(sizeof(uint8_t) == 1);
using result_type = std::array<uint8_t, sizeof(T)>;
result_type result;
for(auto& x : result) {
x = value & 0xFF;
value >>= 8;
}
return result;
}
https://wandbox.org/permlink/ooGuIzZaw8tdffaT
在您展示的特定情况下,您可以使用移位(如注释中所建议的(和逻辑"或"运算将给定的参数移动到目标中,这将给出如下代码:
m_n = (b23 << 16) | (b1 << 8) | b0;
但这是非常具体的情况,你已经给出。如果您的其他变量有不同的类型和/或您想以不同的方式复制内容,则必须调整代码以适应每种用途。
另一种方法(使用相同的例子(,但更容易适应不同的目标类型,是这样的:
uint8_t bytes[4] = { b0, b1, uint8_t(b23 & 0xFF), uint8_t(b23 >> 8) };
memcpy(&m_n, bytes, 4);
首先将字节数组初始化为给定的参数(可以很容易地增加到16个字节(,然后使用memcpy
将字节数组移动到目标中。
后一种方法可以通过使bytes
成为Foo
的成员并在初始值设定项列表中设置其值来进一步"优化":
struct Foo
{
Foo(uint8_t b0, uint8_t b1, uint16_t b23) : bytes{ b0, b1, uint8_t(b23 & 0xFF), uint8_t(b23 >> 8) }
{
memcpy(&m_n, bytes, 4);
}
uint8_t bytes[4];
uint32_t m_n;
};
请随时要求进一步澄清和/或解释。
可能的实现(需要C++17,或参见下文(:
template<typename T, typename... Ts>
constexpr void combine_as_bits_impl(std::size_t offset, unsigned char* out,
const T& x, const Ts&... xs) {
std::memcpy(out + offset, &x, sizeof(T));
if constexpr (sizeof...(Ts) > 0)
combine_as_bits_impl(offset + sizeof(T), out, xs...);
}
template<typename Out, typename... Ts>
constexpr Out combine_as_bits(const Ts&... xs) {
static_assert((sizeof(Ts) + ...) == sizeof(Out));
unsigned char buff[sizeof(Out)];
combine_as_bits_impl(0, buff, xs...);
Out out;
std::memcpy(&out, buff, sizeof(Out));
return out;
}
用法示例:
auto s = combine_as_bits<std::uint32_t>(
std::uint8_t{0x1}, std::uint8_t{0x2}, std::uint16_t{0x3456});
assert(s == 0x34560201);
和
Foo(std::uint8_t b0, std::uint8_t b1, std::uint16_t b23) :
m_n(combine_as_bits<std::uint32_t>(b0, b1, b23)) {}
如果if constexpr
不可用,可以使用简单的重载来终止递归:
constexpr void combine_as_bits_impl(std::size_t, unsigned char*) {}
template<typename T, typename... Ts>
constexpr void combine_as_bits_impl(std::size_t offset, unsigned char* out,
const T& x, const Ts&... xs) {
std::memcpy(out + offset, &x, sizeof(T));
combine_as_bits_impl(offset + sizeof(T), out, xs...);
}
相关文章:
- 为我的 c++ 类介绍制作一个三角形分类器.我有几个问题
- 使用 make 编译 MPI,几个命名空间错误,例如"错误:未知类型名称'使用'?
- 如何返回或护理项目清单基于几个类别
- 我们如何在文本文件中找到C++中的几个单词?
- 关于 std::bitset 构造函数的几个问题?
- 几个 Nt 函数在 Windows 7 x32 上返回STATUS_WAIT_0
- std::stoi 只转换前几个字符
- C++ 通过接口使用从其他几个类继承的类
- 在矢量中使用擦除时双重释放或损坏(快速顶部).如何擦除一个矢量的几个项目知道它们的索引?
- 如何遍历几个每小时一次的根(.root)文件,并将它们组合成更大的每日数据.root文件?
- 我有几个关于参考变量的问题
- 如何将几个变量复制到其他变量
- C++ 两个线程,共享几个整数变量
- 初始化几个用逗号","分隔的变量
- 从几个变量中创建字符串
- C++健全性检查失败:几个变量/内存位置被更改为垃圾,即使我从未访问过它们
- 从文件中读取几个变量类型
- 在 C++ 中易变:我是否应该定义一个可能被几个线程更改的变量作为易失性
- 使用类只是为了维护几个常量变量是个好主意吗?
- 如何定义几个源文件访问的Linux内核变量