【问题标题】:C++ std::fill and std::fill_n error "error C2679"C++ std::fill 和 std::fill_n 错误“错误 C2679”
【发布时间】:2018-08-13 17:55:02
【问题描述】:

我要做什么:

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

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

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

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

我尝试了什么:

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

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

还有

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

其中 MyScuct 是 MY_STRUCT MyScruct

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

错误 C2679:二进制“=”:未找到采用右手的运算符 'const int' 类型的操作数(或没有可接受的转换)

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

【问题讨论】:

  • fillfill_n 期望“填充”一个数组,就像对数组中的每个元素执行 = 0; 一样。我猜您实际上想将结构的每个字节设置为 0;如果是这样,那么 fillfill_n 不是正确的工具
  • 这会改善问题来解释你想要实现的目标
  • 什么是MY_STRUCT
  • 发生这种情况是因为fill 正在尝试做与*&MyScruct = 0; 等效的操作。
  • 试试旧的好的 memset。

标签: c++ visual-studio-2010 c++11 std


【解决方案1】:

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

在现代 C++ 中,设计一个需要 memset 的类是不好的。但是,如果您使用其他人的以这种方式设计的类,那么按照他们的设计使用他们的类是正确的。


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

MyScruct = MY_STRUCT{};

此代码可能与memset 具有相同的效果,也可能不同,具体取决于MY_STRUCT 的详细信息。

【讨论】:

  • 我已经尝试过了,但没有工作,因为他们没有使用 c++11,我认为......他们使用的是 c++03。
  • @DumitruVlad 我建议不要更改原始代码。
  • 如何在默认构造函数中为MY_STRUCT 成员分配0/默认值?它不会产生与MyScruct = MY_STRUCT{};相同的效果吗?
  • @miradham 他可能不想更改类定义;即便如此,这也会引入另一个可能的故障点(例如,您可能忘记设置其中一个成员)
  • 简短回答@miradham,我不能这样做,因为我不允许更改该代码。
【解决方案2】:

在原始代码中,memset 将完全忽略类型系统,只将字节写入原始内存,丢弃之前存在的任何内容(我不得不质疑 “memset 方法是否工作得很好” 实际上工作正常,或者实际上是未定义的)。

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

没有数组,只是一个对象

那么你肯定不想传递sizeof(MyStruct),因为这表示要“填充”多少类型的对象。您只有 一个 对象,而不是具有 sizeof(MyStruct) 元素的数组。

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

我尝试将 memset 更改为更 C++ 标准的方法,即 fill 或 fill_n

std::fillstd::fill_n 是为一系列值分配新值的 C++ 方法,而不是 memset 的 C++ 版本。 memset的C++版本是memset

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

MyStruct s = { };

这是完全有效的 C++,适用于任何版本,从 C++98 到最新标准。这比使用memset 更简单、更安全、更易读。

【讨论】:

  • “我不得不质疑“运行良好的 memset 方法”是否真的运行良好,或者真的没有定义“:你能详细说明一下吗?对于 POD 类型来说是安全的,对吧?
  • @joe_chip 对于可简单复制的类型是安全的。所有 POD 类型都是可简单复制的。我们不知道 OP 的类型是否是 POD。
猜你喜欢
  • 1970-01-01
  • 2013-12-13
  • 2015-09-12
  • 2014-01-12
  • 1970-01-01
  • 2021-09-03
  • 1970-01-01
  • 2014-11-08
  • 1970-01-01
相关资源
最近更新 更多