c++ - C++ 可变参数模板打包到 std::array 并解包
问题描述
我想将变量打包在一个数组中,然后使用这样的接口解包
int x; float y; double z;
auto data = PackArray(x, y, z); // serializes without padding
...
int x; float y; double z;
UnpackArray(data, x, y, z); // copies data from the array to x, y, z
我试过
template<class... T>
constexpr size_t SumOfSizeofs(const T&...)
{
return (sizeof(T) + ...);
}
// Creates array of u8 with size = sum(sizeofs)
template <class A, class ...Rest>
auto PackArray(A& a, Rest&... rest)
{
return std::array<u8, SumOfSizeofs(a, rest...)>; // doesn't work
}
template <class Array, class...Rest>
auto UnpackArray(Array& array, Rest&... rest)
{
// iterates through sizeof each element, copying to its new buffer from the array
}
如果有一个std::packed_tuple
它会很棒...... :(我对模板语法不好,帮助?
解决方案
这是我的尝试:
#include <array>
#include <cstddef>
#include <cstdio>
#include <cstring>
#include <memory>
#include <type_traits>
template <class... T>
[[nodiscard]] auto PackArray(T&&... args) {
static_assert(
(std::is_trivially_copyable_v<std::remove_reference_t<T>> && ...),
"Packing requires trivial-copying");
std::array<std::byte, (sizeof(T) + ... + 0)> data;
std::size_t offet = 0;
(std::memcpy(data.data() + (offet += sizeof(args)) - sizeof(args),
std::addressof(args), sizeof(args)), ...);
return data;
}
template <std::size_t sz, class... T>
auto UnpackArray(std::array<std::byte, sz> const& data, T&... args) {
static_assert(sz == (sizeof(T) + ... + 0), "Mismatch");
static_assert(
(std::is_trivially_copyable_v<std::remove_reference_t<T>> && ...),
"UnPacking requires trivial-copying");
std::size_t offet = 0;
(std::memcpy(std::addressof(args),
data.data() + (offet += sizeof(args)) - sizeof(args),
sizeof(args)), ...);
}
int main() {
int x = 42;
float y = 3.14f;
double z = 2.72;
auto data = PackArray(x, y, z); // serializes without padding
int x1;
float y1;
double z1;
UnpackArray(data, x1, y1, z1);
std::printf("%d, %.2f, %.2f", x1, y1, z1);
}
注意使用std::addressof
以避免对象重载的问题operator&
。
推荐阅读
- c# - .Net Core 3.1 导入的 WCF 参考忽略枚举值
- firebase - Flutter - 当用户从各自的设备上卸载 iOS 和 Android 应用程序时,删除 Firebase Firestore 数据的云功能
- python - 将 dcc.Interval 动态添加到破折号
- javascript - 移动端Safari中,网站添加到主屏幕,导航页面时顶部和底部显示灰色条,如何使其全屏?
- aws-cli - 如何在 aws-cli 中轮询请求状态?
- python - 检查数据框的两列是否在python中具有不同顺序的相同元素
- azure-pipelines - 在 Azure Pipelines 中复制和重命名配置文件
- java - 启动 jar 文件 org.springframework.beans.factory.UnsatisfiedDependencyException 时出错:使用名称创建 bean 时出错
- ios - 应用程序未捕获 iOS NFC 背景读取
- javascript - 带有individuell onclick事件的javascript自动创建按钮