zoukankan      html  css  js  c++  java
  • Effective STL 学习笔记 Item 17: Swap Trick

    假设有若干对象存于一个 vector 中:

    class Widget;
    vector<Widget> vw;
    

    后来由于某些原因,从该容器中删除了若干对象(参考erase-remove idiom )。对于 vector 和 string 来讲, erase()clear() 并不会改变容器的capacity,也就不会改变他们的内存占用。

    swap() 本意是用来交换两个容器的内容( Iterators, pointers, and references),但我们可以用他来快速将容器的 capacity 调整为 合适 的大小:

    vector<Widget>(vw).swap(vw);
    

    巧妙之处在于, vector 的拷贝构造函数仅仅拷贝有用的部分而忽略那些未占用的空间,用这个拷贝构造出来的容器来和 vw 进行 swap() 就可以调整 vw 的 capacity 为一个 相对较小的值

    这里之所以说是 相对较小的值 而不是与 size() 绝对相等,是因为容器的 Implementation 在构造的时候会自己选取合适的值来保证分配的空间足够容纳所有的元素,但这个值可能会比 size() 大, 可参考Item 14

    下面是一个简单的例子,对 vector 进行一些操作,然后输出其 erase, swap,clear 之后的 size 与 capacity:

    #include <vector>
    #include <iostream>
    #include <time.h>
    #include <stdlib.h>
    #include <fstream>
    #include <iterator>
    
    using namespace std;
    
    const int MAX = 1024;
    
    #define show(v, msg)    printf ("%s -- %s: size: %lu, capacity: %lu
    ", 
                                    #v, msg, v.size(), v.capacity());
    
    int main(int argc, char *argv[])
    {
        srand(time(NULL));
    
        printf("Testing vector...
    ");
        vector<int> v;
        show(v, "After init");
    
        v.reserve(MAX);
        show(v, "After reserve()");
    
        for (int i = 0; i < MAX; ++i)
        {
            v.push_back(random()%1000);
        }
        show(v, "After Filling");
    
        v.erase(remove_if(v.begin(), v.end(), [](int x){return x > 100;}), v.end());
        show(v, "After erase()");
    
        vector<int>(v).swap(v);
        show(v, "After swap()");
    
        v.clear();
        show(v, "after clear");
    
        vector<int>().swap(v);
        show(v, "after swap with empty vector");
    
        return 0;
    }
    

    其输出如下:

    Testing vector...
    v -- After init: size: 0, capacity: 0
    v -- After reserve(): size: 0, capacity: 1024
    v -- After Filling: size: 1024, capacity: 1024
    v -- After erase(): size: 106, capacity: 1024
    v -- After swap(): size: 106, capacity: 106
    v -- after clear: size: 0, capacity: 106
    v -- after swap with empty vector: size: 0, capacity: 0
    Program ended with exit code: 0
    
  • 相关阅读:
    【iOS】打印方法名
    【iOS】设备系统版本
    【iOS】receiver type *** for instance message is a forward declaration
    【iOS】获取应用程序本地路径
    hash算法
    redis文档
    Couchbase
    nodejs多核处理
    基于nodejs的消息中心
    nodejs两个例子
  • 原文地址:https://www.cnblogs.com/yangyingchao/p/3402477.html
Copyright © 2011-2022 走看看