【问题标题】:Why does valarray assignment not resize assignee per the documentation?为什么 valarray 分配不根据文档调整受让人的大小?
【发布时间】:2015-10-30 05:59:16
【问题描述】:

代码:

#include <valarray>
#include <iostream>    

using namespace std;

int main()
{
  valarray<int> v0(2, 4);
  valarray<int> v1;
  v1 = v0;
  cout << "v0.size: " << v0.size() << endl;
  cout << "v1.size: " << v1.size() << endl;
  cout << "v0[0]: " << v0[0] << endl;
  cout << "v1[0]: " << v1[0] << endl;
}

输出:

v0.size: 4
v1.size: 0
v0[0]: 2
Segmentation fault

作业:

v1 = v0;

我认为构造函数:

valarray<T>& operator=( const valarray<T>& other );

应该使用,并且根据documentation,我认为应该调整 v1 的大小并将 v0 的内容复制到其中,一个元素一个元素。那么到底发生了什么?

$ g++ --version
g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-11)

【问题讨论】:

  • 您使用的是什么平台、编译器、版本、标准库实现等?工作得很好here
  • 你确定这是你的输出吗?该文本甚至与您传递给 cout 的字符串不匹配。
  • @Bryant 显示的输出与代码不对应。
  • @Praetorian:一定是我的实现之类的。我在 Centos 机器上,但我的组织使用非常旧的库等。 g++ --version g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-11)
  • 等等,我很困惑。有人曾将此称为a GCC bug,但结论是这是符合标准的。这是错误的,或者 cppreference.com 页面是错误的。 (或者在 cppreference.com 页面上没有反映的过程中某处发生了变化)

标签: c++ assignment-operator valarray


【解决方案1】:

因为您使用的是旧 C++。

从 C++11 开始,目标会调整大小以匹配源。
这就是为什么这里的一些贡献者无法重现您的问题(另外,UB 有不可预测的结果)。 这也是为什么the cppreference.com article states that a resize is first performed 的原因(尽管免责声明这仅适用于 C++11 可能已经很好了)。 [现在已修复。]

[C++11: 23.6.2.3] valarray 赋值 [valarray.assign]

valarray&lt;T&gt;&amp; operator=(const valarray&lt;T&gt;&amp; v);

1  *this 数组的每个元素都分配有参数数组的相应元素的值。如果v 的长度不等于*this 的长度,则在执行赋值之前调整*this 的大小以使两个数组的长度相同,就像调用resize(v.size()) 一样。

2   后置条件:size() == v.size()

但是,在 C++03 中,您的代码具有未定义的行为。
这就是为什么您的旧工具链出现分段错误的原因。这也是为什么,当这个问题在 2003 年以a GCC bug 提出时,它被认为无效而被拒绝,因为当时的实现实际上是一致的。

[C++03: 23.3.2.2] valarray 赋值 [valarray.assign]

valarray&lt;T&gt;&amp; operator=(const valarray&lt;T&gt;&amp; v);

1  *this 数组的每个元素都分配有参数数组的对应元素的值。如果参数数组的长度不等于*this 数组的长度,则结果行为是不确定的。

【讨论】:

  • 希望我能 ping @Cubbihe added that textI don't know 在文章中格式化澄清的最佳方式。
  • 我编辑了它。认为这是正确的格式,因为它与范围构造函数描述 here 的格式相匹配。 (所以你现在应该编辑你的答案)
  • 更改了样式,现在看起来像显示的内联修订差异here
  • 我有使用valarray的代码,我一直在使用gnu++98c++03。我希望我能给你买杯啤酒。
  • @Praetorian / LRiO 很高兴看到 cppreference 在没有帮助的情况下修复!
猜你喜欢
  • 1970-01-01
  • 2018-04-20
  • 1970-01-01
  • 2015-04-18
  • 1970-01-01
  • 2012-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多