【问题标题】:How many times std::vector::resize should default-construct new elements?std::vector::resize 应该默认构造多少次新元素?
【发布时间】:2012-07-28 05:32:19
【问题描述】:

我们的团队刚刚遇到了这里http://forums.codeguru.com/archive/index.php/t-514404.html 描述的相同问题,即调用some_vec.resize(new_size),其中N = new_size - some_vec.size() 具有N >= 2,并且VC10 默认构造了所有N 个新元素,而GCC 默认构造了单个元素,作为 prototype 元素,为新元素复制构造它 N 次。

由于这是一个 uuid 的向量,默认构造函数随机初始化每个新实例,我们最终得到 N 倍于 GCC 的相同 uuid 和 N 倍不同的 uuid 与 VC。这足以在一个平台上对我们的测试套件造成严重破坏,但在另一个平台上却没有,而且很难找到。

因此,我的问题是:谁是对的?风投还是海合会?或者这是 C++ 中未指定的那些心爱的角落之一? TIA,--DD

【问题讨论】:

  • 标准已经改变。这是一个类似的问题std::vector, default construction, C++11 and breaking changes
  • 应该注意你的类有点“奇怪”:基本上,你有T x; T y;你有x != y的情况。这需要额外的注意和明确的文档......
  • 构造随机化是一件坏事,你可以在你的例子中看到它。大多数代码假定所有默认构造的对象都是相等的。要解决这些问题,您应该有一个随机化功能。或者创建随机对象的工厂。
  • 感谢大家的快速解答。事实上,我们在 GCC 上使用 C++03,并让 VC10 处于其 C++11 默认模式。是的,我们的 uid 类可以默认构造为空/零 uid,但在 2003 年 9 月引入它时我不在。

标签: c++ stl stdvector


【解决方案1】:

我敢打赌,如果您使用-std=c++0x 编译 GCC,您将获得与使用 MSVC 相同的结果,即 N 个默认构造。这在 C++11 中发生了变化,请参阅 here。现在有两个重载,一个只有默认构造新元素的新大小,另一个使用“原型”参数来复制构造每个新元素。

现在,无论您在何种模式下编译,都可以获得一致的结果,只需使用

v.resize(new_size, T());

背景信息:更改是必要的,因为现在有可以移动但不可复制的类型(如std::unique_ptr)。旧签名要求可复制性。现在,如果您使用需要复制的操作,标准容器类型的第一个模板参数只需要可复制。

【讨论】:

    猜你喜欢
    • 2012-08-24
    • 1970-01-01
    • 2019-10-19
    • 2020-09-22
    • 2011-08-11
    • 2012-07-30
    • 2017-10-26
    相关资源
    最近更新 更多