我在一些项目中使用了这三个帮助函数,作为C memset
函数的一个稍微好一些的替代。目标是简化和澄清代码,并在可能的情况下添加assert
s:
// Zero fills a POD type, such as a structure or union.
template<class T>
void ZeroStruct(T & s)
{
std::memset(&s, 0, sizeof(T));
}
// Zero fills a statically allocated array of POD or built-in types. Array length inferred by the compiler.
template<class T, size_t N>
void ZeroArray(T (&arr)[N])
{
std::memset(arr, 0, sizeof(T) * N);
}
// Zero fills an array of POD or built-in types, with array length provided by the caller.
template<class T>
void ZeroArray(T * arr, size_t arrayLength)
{
assert(arr != nullptr);
assert(arrayLength != 0);
std::memset(arr, 0, sizeof(T) * arrayLength);
}
用法示例:
int arr[128];
ZeroArray(arr);
struct S {
int x;
float y;
};
S s;
ZeroStruct(s);
我想用C++11/14特性进一步改进这些功能。我认为使用static_assert
与std::is_pod
一起确保从未在类实例上调用它们是一个好主意。你同意吗?
另外,我应该让他们成为noexept
吗?
还有其他建议吗?
发布于 2014-10-01 23:07:47
我认为使用static_assert
与std::is_pod
一起确保从未在类实例上调用它们是一个好主意。你同意吗?
让您的代码编写更容易,并防止使用memset错误,这是我可以为您的助手看到的唯一原因。实际上,您正在创建类似于改进版本的bzero
(这是不推荐的,但这是不同的故事)。这里有一个答案。
我不止一次遇到一个类似于:memset(某某对象,size_of_object,0)的bug;//清除编译器不会抱怨的对象.
在需要对结构或数组的内存进行零调整的情况下,仍然很少:
其他情况由初始化(= {0}
或= the_struct()
)覆盖。
最后,为什么PascalCasing
在名称上?bzero
或zero_fill
会更适合C++ (就像用于类型的PascalCasing一样,除非您在Microsoft中)。
还有,我应该让他们除了?
听起来是个好主意(对于前两个版本来说,大小是由类型决定的,而不是显式提供的)。第三个版本是有问题的,有点不清楚,我会完全删除它,并在这种情况下使用memset
/std::fill
来使代码更加明显(可读性和可理解性),因为您已经需要注意提供适当的数组大小--您应该在这里三思而后行,而不是使用不明确的助手(只是个人建议)。
发布于 2014-10-01 10:58:21
不要这样做
您的所有情况都可以使用C++中的普通语法来完成。
// int arr[128];
// ZeroArray(arr);
int arr[128] = {0}; // Zero whole array.
// Or better yet use a vector.
std:vector<int> arr(128); // zero init the vector of 128 elements.
// Or alternatively an array
std::array<int,128> arr(0);
// S s;
// ZeroStruct(s);
S s = S(); // Calls the default constructor for zero initialization.
请参见:
https://codereview.stackexchange.com/questions/64432
复制