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::fill
和 std::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::fill
和 std::fill_n
是将新值分配给值序列的 C++ 方法,而不是 memset
的 C++ 版本。 memset
的 C++ 版本是 memset
!
如果您不想重置结构的值,只需初始化它,那么正确的方法就是:
MyStruct s = { };
这是完全有效的 C++,适用于从 C++98 到最新标准的任何版本。这比使用 memset
.
更简单、更安全、更具可读性
我正在尝试做的事情:
我正在使用不是我的代码工作,我正在尝试重构它。我有一个 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::fill
和 std::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::fill
和 std::fill_n
是将新值分配给值序列的 C++ 方法,而不是 memset
的 C++ 版本。 memset
的 C++ 版本是 memset
!
如果您不想重置结构的值,只需初始化它,那么正确的方法就是:
MyStruct s = { };
这是完全有效的 C++,适用于从 C++98 到最新标准的任何版本。这比使用 memset
.