C++ std::fill 和 std::fill_n 错误 "error C2679"

C++ std::fill and std::fill_n error "error C2679"

我正在尝试做的事情:

我正在使用不是我的代码工作,我正在尝试重构它。我有一个 struct 类型的对象,我们称它为 MY_STRUCTURE ,里面有一些参数。在该代码的旧版本中,他们使用 memset 在所有参数中使用 0 初始化结构。因此,我尝试将该 memset 更改为更符合 C++ 标准的方法,即填充或 fill_n。

此外,我应该提一下...没有数组,只是一个对象,所以我要做的就是在所有地方用 0 初始化该对象。

运行良好的 memset 方法看起来像

this:memset(&MyScruct, 0, sizeof(MyScruct));

我尝试了什么:

我正在尝试像这样使用填充和 fill_n 之一:

std::fill(&MyScruct, &MyScruct+ sizeof(MyScruct), 0);

还有

std::fill_n(&MyScruct, sizeof(MyScruct), 0);

其中 MyScruct 是 MY_STRUCT MyScruct;

在这两种情况下,我都会遇到相同的错误:

error C2679: binary '=' : no operator found which takes a right-hand operand of type 'const int' (or there is no acceptable conversion)

你知道这里发生了什么吗?

如果代码是 memset 正确编写的,则没有理由更改它。 fill 不能替代 memset

在现代 C++ 中,设计 一个 class 要求 memset 是不好的。但是,如果您 使用 别人的 class 是这样设计的,那么按设计使用他们的 class 是正确的。


在现代 C++ 中,您可以设计 class 以便值初始化重置它:

MyScruct = MY_STRUCT{};

此代码可能会或可能不会与 memset 产生相同的效果,具体取决于 MY_STRUCT

的详细信息

在原始代码中,memset 将完全忽略类型系统,只将字节写入原始内存,丢弃之前的任何内容(我不得不质疑 "memset approach which is working perfectly fine" 实际上工作正常,或者确实未定义)。

另一方面,std::fill 使用类型系统,并设置正确类型的值。 0 不是正确类型的值(并且不可分配给该类型),因此您不能 "fill" 带零的结构。

There is not an array, is just an object

那么你绝对不想传递sizeof(MyStruct),因为那表示有多少对象类型传递给"fill"。您只有 一个 对象,而不是包含 sizeof(MyStruct) 个元素的数组。

sizeof(MyStruct)memset 的正确参数,因为它适用于字节,而不是对象。您需要告诉 memset 要写入多少字节。但是 std::fillstd::fill_n 是完全错误的,它们以对象而不是字节为单位(除非偶然 sizeof(MyStruct)==1,但即便如此,它也是一个等待发生的错误)。

I've tried to change that memset to a more c++ standard approach which is fill or fill_n

std::fillstd::fill_n 是将新值分配给值序列的 C++ 方法,而不是 memset 的 C++ 版本。 memset 的 C++ 版本是 memset!

如果您不想重置结构的值,只需初始化它,那么正确的方法就是:

MyStruct s = { };

这是完全有效的 C++,适用于从 C++98 到最新标准的任何版本。这比使用 memset.

更简单、更安全、更具可读性