zoukankan      html  css  js  c++  java
  • stl list使用。(转)

    什么是STL呢?

    STL : standard template library,“标准模版库”的意思。基本上可以这么说,STL是一些“容器”的集合,是算法和一些组件的集合。这些算法和容器的集合是精英中的精英的杰作。它的目的是标准化组件,避免重复开发。

    学习STL,我觉得应该从list学起,没别的,就因为它简单,容易上手。

    首先,我们要明白一些基本概念。

    模板(Template):类、结构等的宏(macro)。正规的名字:范型(generic)。

                     一个类的模板叫:范型类(generic class)。

                    一个函数的模板叫:范型函数(generic function)。

    容器(Container):可容纳一些数据的模版类。STL中有vector、set、map、multimap等

    向量(Vector):基本数组模板,此乃一容器。

    游标(Iterator):是一指针,用来指向STL容器中的元素,也可指向其它元素。

    本篇主要内容:定义和初始化一个list,计算它的元素的数量,从一个list里查找、删除元素等。

    一、定义list。我们可以这样定义一个list。

    //........注意:这样是错误的!!!..............这是我犯的第一个错误

    #include   "string.h"

    #include   "list.h"                     //这儿错误!!

    using namespace std;

    int main(void)

    {

    list<string>   strlist;

    return 0;

    }

    编译会出现如下错误:

    include\list.h(37) : error C2146: syntax error : missing ';' before identifier 'Length'
    include\list.h(37) : error C2501: 'DWORD' : missing storage-class or type specifiers
    include\list.h(37) : error C2501: 'Length' : missing storage-class or type specifiers
    include\list.h(53) : error C2146: syntax error : missing ';' before identifier 'GetPrevLink'
    include\list.h(53) : error C2433: 'WINAPI' : 'inline' not permitted on data declarations
    include\list.h(53) : fatal error C1004: unexpected end of file found

    原因其实很简单:"list"和"list.h" 是完全不同的,“list.h” 是c形式的双向链表,而“list”是标准的c++的容器。

    正确的应该这样:

    #include "string"

    #include "list"

    using namespace std;

    int main(void)

    {

    list<string>   strlist;

    return 0;

    }

    编译你会发现一大队错误不见了,取而代之的是一大堆警告。不同紧张,这是正常现象,有时候编译器对标准c++ stl 支持不是太好,就会出现这种现象,完全可以不理会。

    到目前为止,我们只是定义了一个list,并没有做任何事情。

    现在我们来把一个字符串装进这个list。再作之前,有一个东东需要我们了解,那就是“值类型”。

    ”值类型“ 就是list 中对象的类型,这儿是string 字符串。

    我们可以使用list的成员函数push_back()、push_font()插入元素到list中。是这么调用的:

    #include "string.h"
    #include "list"
    using namespace std;


    int main(void)
    {
    list<string> strlist;
    strlist.push_back("waring1:");
    strlist.push_back("exception");
    strlist.push_front("有错误:");

    return 0;
    }

    list的成员函数push_back()把一个对象放到一个list的后面,而 push_front()把对象放到前面。

    我通常把一些错误信息push_back()到一个list中去,然后push_front()一个标题到list中,这样它就会在这个错误消息以前打印它了。

    可是我们怎么使用我们放进去的元素呢?我们可以通过Iterator来访问他们,( ^_^ 还记不记得Iterator是什么?一指针而已!)

    在具体操作中,我还有了额外的收获。我本想输出一个字符串,此字符串是string型,结果出现string 没有重载<<的错误,查了一下才知道应该包含”string“   而不是”string.h“。由于C++是从C扩展而来,所以一般"XXX.h"是C头文件,而“XXX”才是C++的。这儿要注意了,不要跟我犯一样的错误。

    好,下面遍历该list

    #include "string"
    #include "list"
    #include "iostream"
    using namespace std;


    int main(void)
    {
    list<string> strlist;
    strlist.push_back("waring1:");
    strlist.push_back("exception");
    strlist.push_front("有错误:");

    list<string>::iterator   pstrlist;
    pstrlist=strlist.begin();
    for(;pstrlist!=strlist.end();pstrlist++)
    {
       cout<<*pstrlist;
    }

    return 0;
    }

    这时会报 二进制“<<”: 没有找到接受“std::basic_string<_Elem,_Traits,_Ax>”类型的右操作数的运算符(或没有可接受的转换) 的错误。

    因为string没有cout输出重载,应该改为 pstrlist

    需要注意的是:Iterator这个对象没有重载 大于 >   或 小于 <       , 只有 !=

    还有就是:在 list 容器中,我们不能用strlist.begin()+2来指向list中的第三个对象,因为STL的list是以双链的list来实现的,它不支持随机存取。vector和deque(向量和双端队列)和一些其他的STL的容器可以支持随机存取。

    至此,我们对STL已经有了一个初步的认识,这仅仅是一个开端,只是皮毛。后面的更精彩。

    STL 还为我们设计了通用算法,这样我们连循环都不用做了。哈哈,爽!

    比如 上面的遍历,就可以用 for_each(),他是STL为我们做的,及其方便。

    一定要记得包含头文件“algorithm“

    #pragma warning(disable:4786)

    #include "string"
    #include "list"
    #include "iostream"
    #include "algorithm"

    using namespace std;

    void print(string &str)
    {
    cout<<str;
    }

    int main(void)
    {
    list<string> strlist;
    strlist.push_back("waring1:");
    strlist.push_back("exception");
    strlist.push_front("有错误:");


    for_each(strlist.begin(),strlist.end(),print);

    return 0;

    }

    这是for_each()的源码,可以研究一下

    template<class    _init,    class    _fn1>    inline   
       _fn1    for_each(_init    _first,    _init    _last,    _fn1    _func)   
        
                       //    perform    function    for    each    element   
                       for    (;    _first    !=    _last;    ++_first)   
                                       _func(*_first);   
                       return    (_func);   
        

    这里一个小技巧,如果编译过程中,讨厌warning4786,可以添加参数将其屏蔽掉。

    #pragma    warning(    disable      xxxx)   
        
       xxxx是warning的编号   

    其它的同理操作就行了。

  • 相关阅读:
    [Debug] A strange error encountered today in ROS
    实操 | 安装一台3D打印机
    实操 | Getting started with Baxter Research Robot ...
    学习笔记 | What is Monocular Vision?
    路线图 | Roadmap of SLAM Research
    路线图 | Road-map of Cracking the Coding Interview as a C++ Developer
    实操 | Implementing Cartographer ROS on TurtleBots
    实操 | Implementing Google's Open Source Slam "Cartographer" demos in ROS / rviz
    科技新闻 | Google's Open Source SLAM Library ---- Cartographer
    实操 | Implementing "slam_karto" package on a Freight robot
  • 原文地址:https://www.cnblogs.com/likwo/p/1684810.html
Copyright © 2011-2022 走看看