Правильный способ инициализации std::array из массива C

#c #pointers #stl

#c #массивы #алгоритм #инициализация #Копировать

Вопрос:

Я получаю массив из C API, и я хотел бы скопировать его в std::array для дальнейшего использования в моем коде C . Итак, каков правильный способ сделать это?

Я использую 2 для этого, один из них:

 struct Foo f; //struct from C api that has a uint8_t kasme[32] (and other things)

c_api_function(amp;f);
std::array<uint8_t, 32> a;
memcpy((void*)a.data(), f.kasme, a.size());
  

И это

 class MyClass {
  std::array<uint8_t, 32> kasme;
  int type;
public:
  MyClass(int type_, uint8_t *kasme_) : type(type_)
  {
      memcpy((void*)kasme.data(), kasme_, kasme.size());
  }
  ...
}
...
MyClass k(kAlg1Type, f.kasme);
  

Но это кажется довольно неуклюжим. Существует ли идиоматический способ сделать это, который, предположительно, не включает memcpy ? Для MyClass ` возможно, мне лучше с
конструктор, принимающий std::array, который перемещается в элемент, но я также не могу найти правильный способ сделать это. ?

Комментарии:

1. Почему бы и нет std::copy ?

2. за исключением того, что это еще не официально: auto x = std::to_array<uint8_t, 32>(cArrayPtr);

Ответ №1:

Вы можете использовать алгоритм, std::copy объявленный в заголовке <algorithm> . Например

 #include <algorithm>
#include <array>

//... 

struct Foo f; //struct from C api that has a uint8_t kasme[32] (and other things)

c_api_function(amp;f);
std::array<uint8_t, 32> a;
std::copy( f.kasme, f.kasme   a.size(), a.begin() );
  

Если f.kasme это действительно массив, то вы также можете написать

 std::copy( std::begin( f.kasme ), std::end( f.kasme ), a.begin() );
  

Комментарии:

1. @binary01 Это моя ошибка.:) Я удалил эту часть сообщения.:)

2. Это кажется немного рискованным. Я бы позволил, чтобы количество копируемых символов определялось целью, а не источником, чтобы избежать переполнения массива. Это можно сделать с помощью std::copy_n : std::copy_n(f.kasme, a.size(), a.begin());