patterncppMinor
A defined macro to copy selected values of std::vector to an array using std::copy
Viewed 0 times
stdarraymacroselectedusingvaluesvectordefinedcopy
Problem
Thought I share this piece of code to the world. But be aware, I am not sure if this piece of code is safe and efficient. Feel free to improve it or give some feedback and suggestions.
#pragma region DOCUMENTATION ON: STD_COPY_VECTOR_TO_ARRAY
//////////////////////////////////////////////////////////////////////////////
// MACRO: STD_COPY_VECTOR_TO_ARRAY( Vector, Position, Length, Array ) //
// //
// DESCRIPTION: //
// A defined macro that is created to copy selected values of std::vector //
// an array. This defined macro takes 4 arguments. //
// //
// ARGUMENTS: //
// Vector - The std::vector that contains the values that will be copied. //
// Position - Position of the first value from Vector to be copied. //
// Note: The first value of Position is marked by the value of 0 and not 1. //
// Length - Amount of values to be copied from Vector. //
// Array - The Array that the values will be copied to. //
// //
// TIPS: //
// #1 - To copy all values within Vector, set the value of Position to 0 //
// and set the value of Length to the size of Vector (std::vector::size). //
//////////////////////////////////////////////////////////////////////////////
#pragma endregion
#define STD_COPY_VECTOR_TO_ARRAY( Vector, Position, Length, Array ) \
std::copy( Vector.begin( ) + Position, \
Vector.begin( ) + Position + Length , \
Array )Solution
Basically, there are very few places in C++ where you want to use Macros. A lot of old C code used function-like macros because of performance reasons - calling a function requires creating a new stack frame. They were also used to get away from C's type system. With C++,
In C++11, we can do better still - an erroneous length passed in above will cause problems, and will be hard to detect:
This will be just as efficient as the macro version, however, we also gain type safety, as well as (easy) bounds checking.
We can also improve on it. So that it handles other container types:
inline functions and templates remove the need for this 99% of the time.template
inline void copy_vector_to_array(const std::vector& vec,
std::size_t position,
std::size_t length,
T* array)
{
std::copy(vec.begin() + position, vec.begin() + position + length, array);
}In C++11, we can do better still - an erroneous length passed in above will cause problems, and will be hard to detect:
#include
#include
#include
#include
template
inline void copy_vector_to_array(const std::vector& vec,
std::size_t position,
std::size_t length,
std::array& array)
{
assert(length <= N);
std::copy(std::begin(vec) + position, std::begin(vec) + position + length,
std::begin(array));
}This will be just as efficient as the macro version, however, we also gain type safety, as well as (easy) bounds checking.
We can also improve on it. So that it handles other container types:
template
inline void copy_container_to_array(const C& container,
std::size_t position,
std::size_t length,
std::array& array)
{
assert(length <= N);
std::copy(std::next(std::begin(vec), position), std::next(std::begin(vec), position + length),
std::begin(array));
}Code Snippets
template <typename T>
inline void copy_vector_to_array(const std::vector<T>& vec,
std::size_t position,
std::size_t length,
T* array)
{
std::copy(vec.begin() + position, vec.begin() + position + length, array);
}#include <vector>
#include <array>
#include <iterator>
#include <cassert>
template <typename T, std::size_t N>
inline void copy_vector_to_array(const std::vector<T>& vec,
std::size_t position,
std::size_t length,
std::array<T, N>& array)
{
assert(length <= N);
std::copy(std::begin(vec) + position, std::begin(vec) + position + length,
std::begin(array));
}template <typename C, std::size_t N>
inline void copy_container_to_array(const C& container,
std::size_t position,
std::size_t length,
std::array<typename C::value_type, N>& array)
{
assert(length <= N);
std::copy(std::next(std::begin(vec), position), std::next(std::begin(vec), position + length),
std::begin(array));
}Context
StackExchange Code Review Q#23136, answer score: 4
Revisions (0)
No revisions yet.