C++ 可变参数模板打包到 std::array 并解包

标签 c++ templates

我想将变量打包到一个数组中,然后使用这样的接口(interface)解包

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++ 可变参数模板打包到 std::array 并解包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66483145/

相关文章:

amazon-web-services - 如何在速度模板中添加生成随机 UUID 等功能,用于 API 网关中的请求/响应映射

c++ - 库不是只有标题的原因是什么?

c++ - OpenCL 在调用 clGetPlatformIDs 时崩溃

c++ - const 引用和虚拟模板继承

带有 'const' 的 C++ 模板

c++在模板中使用元组作为参数包

c++ - 在 C++ 中寻找线性方程组的最优解

C++ 从一个字符中获取指定的部分

c++ - 如何初始化和更改数组作为结构的成员变量?

C++ createObject() 工厂