Search code examples
c++c++17stdvectorstdarray

How to append or insert std::array elements into a std::vector?


I'm relatively new to c++ and I've tried to do some research, but while searching online I've mainly come across C arrays rather than std::array. What are the most efficient ways to append std::array elements into a std::vector, and to insert std::array elements into a std::vector? Should I use STL functions such as std::copy? I'm currently using C++17, MinGW64.


Solution

  • "Appending" values can mean two things - you either want to copy/duplicate the elements in question, or you don't need them in the source container aftwards and might also move them into the destination container. Also, it makes sense to distinguish between insertion at construction time vs. appending to an existing, already constructed container: if you can, always construct a container with the elements that it's supposed to own.

    1. Copy-append std::array elements to an already constructed std::vector:

      std::vector<T> dest;
      std::array<T, N> source;
      
      // ...
      
      dest.insert(dest.end(), source.cbegin(), source.cend());
      
    2. Move-append std::arrayelements to an already constructed std::vector.

      std::vector<T> dest;
      std::array<T, N> source;
      
      // ...
      
      dest.insert(dest.end(), std::move_iterator(source.begin()),
                  std::move_iterator(source.end()));
      
    3. Copy std::array elements into a std::vector at construction:

      std::array<T, N> source;
      
      // ...
      
      std::vector<T> dest(source.cbegin(), source.cend());
      
    4. Move std::array elements into a std::vector at construction:

      std::array<T, N> source;
      
      // ...
      
      std::vector<T> dest(std::move_iterator(source.begin()),
                          std::move_iterator(source.cend()));
      

    There is not much to add here when talking about insertion into the middle - the only notable difference is that it will always be less efficient, as the remaining elements in the destination std::vector will be move-constructed (which is O(N)).

    Note also that for appending elements, there is std::move and std::copy from the <algorithm> header (where std::copy can be used with std::move_iterators). However, these cannot be as efficient as a direct call to std::vector::insert, because the former operates on the iterator abstraction and processes the copy/move one element at a time without knowing about the storage details of the destination (this can result in multiple buffer resizings), while the latter is a std::vector member function and will resize the buffer only once (if required).