Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用模板元编程优化结构序列化_C++_C++17_Template Meta Programming - Fatal编程技术网

C++ 使用模板元编程优化结构序列化

C++ 使用模板元编程优化结构序列化,c++,c++17,template-meta-programming,C++,C++17,Template Meta Programming,我想在32位对齐的平台(armv7)上序列化结构。其思想是将结构成员(我提取)序列化为std::byte数组,然后复制到std::uint32\t数组(输出缓冲区) 两个序列化程序如下所示: // serialize to std::byte array template <typename T, class OutputIterator, typename std::enable_if_t< std::is_same<typename std::iterator

我想在32位对齐的平台(armv7)上序列化结构。其思想是将结构成员(我提取)序列化为
std::byte
数组,然后复制到
std::uint32\t
数组(输出缓冲区)

两个序列化程序如下所示:

// serialize to std::byte array
template <typename T, class OutputIterator, 
  typename std::enable_if_t<
    std::is_same<typename std::iterator_traits<OutputIterator>::value_type, 
      std::byte>::value, int> = 0>
std::size_t serialize(const T& value, OutputIterator iterator)
{
  std::size_t offset = 0; 
  visit_struct::for_each(value,
  [&](const char*, const auto& element) 
  {
    auto raw = reinterpret_cast<std::byte const*>(&element);
    auto type_size = sizeof(decltype(element));
    std::copy(raw, std::next(raw, type_size), std::next(iterator, offset));
    offset += type_size;
  });
  return offset;
}

// serialize to std::uint32_t array
template <typename T, class OutputIterator, 
  typename std::enable_if_t<
    std::is_same<typename std::iterator_traits<OutputIterator>::value_type, 
      std::uint32_t>::value, int> = 0>
std::size_t serialize(const T& value, OutputIterator iterator)
{
  constexpr std::size_t type_size = ext::mock_maker<T>::size;
  constexpr std::size_t aligned_type_size = (type_size + 4 - 1) / 4;
  std::array<std::byte, type_size> raw;
  serialize(value, raw.begin()); 
  auto raw_aligned = reinterpret_cast<std::uint32_t const*>(raw.data());
  std::copy(raw_aligned, std::next(raw_aligned, aligned_type_size), iterator);
  return aligned_type_size;
}
//序列化为std::字节数组
模板=0>
std::size\u t序列化(常量t和值,输出迭代器)
{
标准::尺寸偏差=0;
访问_struct::for_each(值,
[&](常量字符*,常量自动和元素)
{
自动原始=重新解释铸件(&E);
自动类型_size=sizeof(decltype(element));
std::copy(raw,std::next(raw,type_size),std::next(迭代器,偏移量));
偏移量+=类型大小;
});
返回偏移量;
}
//序列化到std::uint32\u t数组
模板=0>
std::size\u t序列化(常量t和值,输出迭代器)
{
constexpr std::size\u t type\u size=ext::mock\u maker::size;
constexpr std::size\u t aligned\u type\u size=(type\u size+4-1)/4;
std::数组原始;
序列化(值,raw.begin());
自动原始对齐=重新解释强制转换(raw.data());
std::copy(原始对齐,std::next(原始对齐,对齐类型大小),迭代器);
返回对齐的\u类型\u大小;
}

我希望编译器能够以某种方式优化中间表示形式,即
std::byte
数组,但我的建议是另一种方式。有没有一种方法可以优雅地实现这一点?

另一方面,
(type_size+3)/4
不是一种溢出安全的细胞分割方法。请看@J.Schultke,谢谢你的链接!我原以为我的答案优化了多余的拷贝,但我错了。有趣的是,在x86上,这个优化非常好,只优化了一堆
mov
s。在arm上,无论我做什么,GCC都会发出对
memcpy
的实际调用。通用性重要吗?如果是,请考虑编写一个输出迭代器适配器,该适配器使用<代码> STD::Byth,并将它们打包成<代码> UTIT32×T 。如果没有,请考虑在接口中使用<代码> STD::Basic SythBuff。