将std :: array从指针初始化为优雅的缓冲区?

时间:2017-09-10 01:02:27

标签: c++ arrays c++11

什么是适当的'在C ++ 11及更高版本中将std::array从指针初始化为缓冲区?

我目前有

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;
}

在我的代码中,但这只是显得草率而且效率低下 - 看起来这应该是使用标准库中的某些东西,但是我无法通过搜索在任何地方找到它。

3 个答案:

答案 0 :(得分:3)

有一些选项,假设字节总是至少有大小有效元素。

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

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

您也可以使用std::memcpy,但我更喜欢上述两种,因为它们也适用于非字节数据。

答案 1 :(得分:2)

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

话虽如此,但这并不是更有效率 - 它更紧凑,实际上主要是品味问题。

答案 2 :(得分:1)

为了好玩,我提出了基于统一初始化和可变参数模板的以下解决方案。

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>{}); }

不幸的是使用只能从C ++ 14获得的std::index_sequencestd::make_index_sequence,但很容易开发C ++ 11的替代品。

以下是一个完整的工作示例

#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;
 }