I wonder what is the ideal way if you want to fill an array with a default value n:
#include <cstring> // for memset
#include <algorithm> // for fill_n
static constexpr int N = 100;
int a[N];
static constexpr int defaultValue = -1;
void* memset( void* dest, int ch, std::size_t count );
memset(a, defaultValue, sizeof(a));
(memset) converts the value ch to unsigned char and copies it into each of the first count characters of the object pointed to by dest. If the object is a potentially-overlapping subobject or is not TriviallyCopyable (e.g., scalar, C-compatible struct, or an array of trivially copyable type), the behavior is undefined. If count is greater than the size of the object pointed to by dest, the behavior is undefined.
or
constexpr OutputIt fill_n( OutputIt first, Size count, const T& value );
fill_n(a, N, defaultValue);
(fill_n) assigns the given value to the first count elements in the range beginning at first if count > 0. Does nothing otherwise.
I am looking for insights, I know how to read the documentation of course!
edit: defaultValue might not be only -1.
Both functions do different things. Sure, they fill a block of memory, but the way they do it is completely different.
memset
operates at the byte level. defaultValue
is hacked down to an unsigned char
, so a defaultValue
greater than what can fit into a single byte gets cut down to size and information is lost. The now-byte-sized value is applied individually to every byte, not every int
in the array. In the case of -1 you get "lucky" because four bytes worth of 0xFF looks the same, 0xFFFFFFFF, as a two's compliment -1 in the world of 32-bit integers. No such luck for most other numbers. 1, for example, will not result in an array full of int
's set to 1, it's filled with 0x01010101, or 16843009.
fill_n
, on the other hand, respects the array element's type. Every int
in the array will be set to defaultValue
. in the case of a defaultValue
of 1, the array will be full of 1s. defaultValue
of 256, provides an array full of 256.
In terms of speed, it probably won't matter much. Memory read or written in bytes is a rare sight these days. Writing whole int
s at a time may be faster. But a good memset
implementation knows this and will be exploiting it. If it doesn't, the compiler likely will.