Let\'s say I have defined a zero_initialize() function:
template
T zero_initialize()
{
T result;
std::memset(&result,
What (minimal) trait / concept can guarantee memsetting an object is well defined?
Per the std::memset reference on cppreference the behavior of memset on a non TriviallyCopyable type is undefined. So if it is okay to memset a TriviallyCopyable then you can add a static_assert to your class to check for that like
template
T zero_initialize()
{
static_assert(std::is_trivial_v, "Error: T must be TriviallyCopyable");
T result;
std::memset(&result, 0, sizeof(result));
return result;
}
Here we use std::is_trivial_v to make sure that not only is the class trivially copyable but it also has a trivial default constructor so we know it is safe to be zero initialized.
Should I use
std::uninitialized_fillinstead ofstd::memset? And why?
You don't need to here since you are only initializing a single object.
Is this function made obsolete by one of C++ initialization syntaxes for a subset of types? Or will it be with the upcoming of future C++ versions?
Value or braced initialization does make this function "obsolete". T() and T{} will give you a value initialized T and if T doesn't have a default constructor it will be zero initialized. That means you could rewrite the function as
template
T zero_initialize()
{
static_assert(std::is_trivial_v, "Error: T must be TriviallyCopyable");
return {};
}