什么是适当的'在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;
}
在我的代码中,但这只是显得草率而且效率低下 - 看起来这应该是使用标准库中的某些东西,但是我无法通过搜索在任何地方找到它。
答案 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_sequence
和std::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;
}