首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >memset()的包装模板函数

memset()的包装模板函数
EN

Code Review用户
提问于 2014-10-01 18:22:29
回答 2查看 1.6K关注 0票数 5

我在一些项目中使用了这三个帮助函数,作为C memset函数的一个稍微好一些的替代。目标是简化和澄清代码,并在可能的情况下添加asserts:

代码语言:javascript
运行
复制
// 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);
}

用法示例:

代码语言:javascript
运行
复制
int arr[128];
ZeroArray(arr);

struct S {
    int   x;
    float y;
};
S s;
ZeroStruct(s);

我想用C++11/14特性进一步改进这些功能。我认为使用static_assertstd::is_pod一起确保从未在类实例上调用它们是一个好主意。你同意吗?

另外,我应该让他们成为noexept吗?

还有其他建议吗?

EN

回答 2

Code Review用户

回答已采纳

发布于 2014-10-02 07:07:47

我认为使用static_assertstd::is_pod一起确保从未在类实例上调用它们是一个好主意。你同意吗?

让您的代码编写更容易,并防止使用memset错误,这是我可以为您的助手看到的唯一原因。实际上,您正在创建类似于改进版本的bzero (这是不推荐的,但这是不同的故事)。这里有一个答案

我不止一次遇到一个类似于:memset(某某对象,size_of_object,0)的bug;//清除编译器不会抱怨的对象.

在需要对结构或数组的内存进行零调整的情况下,仍然很少:

  1. 当您重用结构/数组时(但是哪个库函数真正需要它?)
  2. 出于安全考虑(不要将密码留在内存中)。

其他情况由初始化(= {0}= the_struct())覆盖。

最后,为什么PascalCasing在名称上?bzerozero_fill会更适合C++ (就像用于类型的PascalCasing一样,除非您在Microsoft中)。

还有,我应该让他们除了?

听起来是个好主意(对于前两个版本来说,大小是由类型决定的,而不是显式提供的)。第三个版本是有问题的,有点不清楚,我会完全删除它,并在这种情况下使用memset/std::fill来使代码更加明显(可读性和可理解性),因为您已经需要注意提供适当的数组大小--您应该在这里三思而后行,而不是使用不明确的助手(只是个人建议)。

票数 3
EN

Code Review用户

发布于 2014-10-01 18:58:21

不要这样做

您的所有情况都可以使用C++中的普通语法来完成。

代码语言:javascript
运行
复制
// 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.

请参见:

包含其他对象的类的C++隐式复制构造函数

初始化C++结构的正确方法

C++结构有默认构造函数吗?

票数 3
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/64432

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档