在不破坏保留元素的情况下更改向量的大小

Posted

技术标签:

【中文标题】在不破坏保留元素的情况下更改向量的大小【英文标题】:Change size of vector without destroying reserved elements 【发布时间】:2014-01-18 14:50:41 【问题描述】:

使用reserve() 后跟push_back() 可能比调整向量大小和稍后执行分配更快——如std::vector reserve() and push_back() is faster than resize() and array index, why? 所示。

但是,如果我进行分配而不是使用push_back(),则向量的大小仍然是0

# include <vector>
int main() 

    std::vector<int> x;
    x.reserve(10);
    x[0] = 10, x[1] = 9, x[2] = 8, x[3] = 7, x[4] = 6;
    x[5] = 5,  x[6] = 4, x[7] = 3, x[8] = 2, x[9] = 1;

    std::cout << x[2] << std::endl;
    std::cout << "SIZE: " << x.size() << std::endl; // 'size()' is 0

    x.resize(10); // removes former entries, since the vector had 'size() = 0'
    std::cout << x[2] << std::endl;
    std::cout << "SIZE: " << x.size() << std::endl; // 'size()' is 10,
                                                    // but values are gone


输出:

8
SIZE: 0
0
SIZE: 10

如何在不破坏 保留 条目的情况下更改矢量的大小?当然,我仍然想使用reserve(),以降低分配成本——我知道我需要的确切大小。

【问题讨论】:

请阅读文档:vector::reserve 只是为请求的数量保留容量 - 内存未初始化 如果你用的是c++11,可以std::vector&lt;int&gt; x 10,9,...; @DieterLücking 内存未初始化,但无论如何都已分配,不是吗?还是分配给push_back() 另外,如果您知道您需要的确切尺寸,为什么不使用std::array&lt;int, 10&gt;?编辑:根据this,在所有其他情况下,函数调用不会导致重新分配并且向量容量不受影响。 @Gasim 我正在编写一个小型序列化程序。用户打包一个向量,并将其大小写入缓冲区。我知道拆包期间的确切尺寸,但我仍在处理vector 【参考方案1】:

当我想避免 vector 元素的值初始化时,我使用分配器适配器来完全删除该行为:

// Allocator adaptor that interposes construct() calls to
// convert value initialization into default initialization.
template <typename T, typename A=std::allocator<T>>
class default_init_allocator : public A 
  typedef std::allocator_traits<A> a_t;
public:
  template <typename U> struct rebind 
    using other =
      default_init_allocator<
        U, typename a_t::template rebind_alloc<U>
      >;
  ;

  using A::A;

  template <typename U>
  void construct(U* ptr) 
    // value-initialization: convert to default-initialization.
    ::new (static_cast<void*>(ptr)) U;
  
  template <typename U, typename...Args>
  void construct(U* ptr, Args&&... args) 
    // Anything else: pass through to the base allocator's construct().
    a_t::construct(static_cast<A&>(*this),
                   ptr, std::forward<Args>(args)...);
  
;

默认初始化很简单的类型——比如int——根本不会被初始化。 (Live demo at Coliru)

【讨论】:

+1 感谢您的支持!我想这是我想要的最好的选择 - 只是希望它更简单(:编辑:啊,我的错!我无法更改向量结构,因为它是由用户给出的(我正在编写一个简单的序列化程序)。 @Rubens 如果您可以选择 Boost,boost::vector optionally supports default initialization。

以上是关于在不破坏保留元素的情况下更改向量的大小的主要内容,如果未能解决你的问题,请参考以下文章

如何在不破坏向后兼容性的情况下更改 DataContract 属性的类型?

在不破坏旧 URL 的情况下更改 wordpress 中的 URL 方案

如何在不破坏布局“流程”的情况下使用 css 旋转元素?

顺风:在不破坏行的情况下增加弯曲的间隙

如何在不破坏图像纵横比的情况下调整 QImage 或 QML 图像的大小以适应父容器

在不破坏现有迁移的情况下重命名 Django 模型