简体   繁体   English

从指针初始化std :: array优雅地进入缓冲区?

[英]Initialising std::array from pointer into a buffer elegantly?

What is the 'proper' way in C++11 and beyond to initialise a std::array from a pointer into a buffer? 在C ++ 11及更高版本中,将std::array从指针初始化到缓冲区的“正确”方法是什么?

I currently have 我目前有

using guid_t = std::array<uint8_t, 16>;

inline guid_t make_guid(const uint8_t * bytes)
{
    guid_t res;
    for (int i = 0; i < res.size(); i++)
    {
        res[i] = bytes[i];
    }
    return res;
}

in my code but this just appears sloppy and inefficient - it seems like this should be a one liner using something in the standard libraries however I can't find it anywhere via searching. 在我的代码中,但这显得草率和低效-似乎这应该是在标准库中使用某些东西的一种衬里,但是我无法通过搜索在任何地方找到它。

There are a handful of options, assuming that bytes always have at least size valid elements. 假设字节始终至少具有大小有效的元素,则有几种选择。

std::copy_n(bytes, res.size(), res.begin());

or 要么

std::copy(bytes, bytes+res.size(), res.begin());

You could also use std::memcpy , but I prefer the above two, as they work with non-byte data as well. 您也可以使用std::memcpy ,但是我更喜欢上面两个,因为它们也可以处理非字节数据。

std::copy(bytes, bytes + guid.size(), guid.begin());

话虽如此,这并不是说效率更高-它稍微更紧凑,实际上主要是口味问题。

Just for fun, I propose the following solution based on uniform initialization and variadic templates. 为了好玩,我基于统一的初始化和可变参数模板提出以下解决方案。

template <std::size_t ... Is>
inline guid_t make_guid_h (uint8_t const * bytes,
                           std::index_sequence<Is...> const &)
 { return { { bytes[Is] ... } }; }

inline guid_t make_guid (uint8_t const * bytes)
 { return make_guid_h(bytes,
      std::make_index_sequence<std::tuple_size<guid_t>::value>{}); }

Unfortunately use std::index_sequence and std::make_index_sequence , that are available only from C++14, but it's easy develop a substitute for C++11. 不幸的是,使用std::index_sequencestd::make_index_sequence ,它们仅在C ++ 14中可用,但是开发C ++ 11的替代品很容易。

The following is a full working example 以下是完整的工作示例

#include <array>
#include <utility>
#include <iostream>

using guid_t = std::array<uint8_t, 16>;

template <std::size_t ... Is>
inline guid_t make_guid_h (uint8_t const * bytes,
                           std::index_sequence<Is...> const &)
 { return { { bytes[Is] ... } }; }

inline guid_t make_guid (uint8_t const * bytes)
 { return make_guid_h(bytes,
      std::make_index_sequence<std::tuple_size<guid_t>::value>{}); }

int main ()
 {
   uint8_t foo []
      = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53 };

   auto bar = make_guid(foo);

   for ( auto const & ui : bar )
      std::cout << int(ui) << ", ";

   std::cout << std::endl;
 }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM