如何将多个变量拷贝至单个变量?多变量场景代码优化咨询
解决多变量拼接到大整数的繁琐memcpy问题
嘿,这个场景我太懂了——当要把一堆零散的小变量逐个拷贝到一个大整数成员里时,重复写memcpy简直是折磨,尤其是变量多到15个的时候。这里有几个简洁的方案,帮你彻底摆脱重复代码的噩梦:
方案1:C++17+ 可变参数模板 + 折叠表达式(最推荐)
直接把构造函数改成可变参数模板,用折叠表达式自动处理每个参数的拷贝和偏移计算,不管你传多少个参数,代码都保持简洁:
#include <cstring> #include <cstdint> struct Foo { template<typename... Args> Foo(Args... args) { // 编译期检查:确保参数总大小和m_n匹配,避免内存溢出 static_assert((sizeof(Args) + ...) == sizeof(m_n), "Total size of arguments must match m_n's size!"); uint8_t* dest = reinterpret_cast<uint8_t*>(&m_n); size_t offset = 0; // 折叠表达式逐个处理参数:完成拷贝+更新偏移的重复操作 ((std::memcpy(dest + offset, &args, sizeof(args)), offset += sizeof(args)), ...); } uint32_t m_n; };
这个写法的核心是让编译期帮你完成重复工作:不管你传1个还是15个参数(只要总大小符合要求),都不用手动修改构造函数逻辑,还能避免手动计算偏移时容易犯的错误。
方案2:数组初始化 + 一次性拷贝(适合同类型参数)
如果你的参数都是相同类型(比如全是uint8_t),可以直接把参数打包成临时数组,然后一次性拷贝到m_n里,代码更直观:
#include <cstring> #include <cstdint> struct Foo { Foo(uint8_t... args) { static_assert(sizeof...(args) == sizeof(uint32_t), "Number of uint8_t arguments must match m_n's size!"); uint8_t temp_bytes[] = {args...}; std::memcpy(&m_n, temp_bytes, sizeof(temp_bytes)); } uint32_t m_n; };
如果参数是混合类型,这个方案就不太适用了,但同类型场景下,它的可读性会更高。
方案3:std::tuple + std::apply(C++17+,灵活扩展)
如果需要先对参数做一些预处理,或者想借助tuple的其他特性,可以把参数放进tuple,再用std::apply遍历处理:
#include <tuple> #include <cstring> #include <cstdint> struct Foo { template<typename... Args> Foo(Args... args) { static_assert((sizeof(Args) + ...) == sizeof(m_n), "Total size mismatch!"); auto args_tuple = std::make_tuple(args...); uint8_t* dest = reinterpret_cast<uint8_t*>(&m_n); size_t offset = 0; std::apply([&](auto&&... elem) { ((std::memcpy(dest + offset, &elem, sizeof(elem)), offset += sizeof(elem)), ...); }, args_tuple); } uint32_t m_n; };
这个方案和方案1效果类似,但更适合需要对参数进行分组、排序等额外操作的场景。
不管选哪个方案,核心思路都是用编译期逻辑替代手动重复代码,这样哪怕参数数量增加到15个,你的代码也不会变得臃肿,还能减少人为失误。
内容的提问来源于stack exchange,提问作者Igor Pugachev
相关产品推荐
相关产品推荐

