C++ STL学习 List iterator

  • Post author:
  • Post category:其他


环境: windows 7 x64, VC 6.0

STL List 中的 iterator存的是什么? 取元素使用 * 运算,比如 *iterSTList ,那么 iterSTList 是指针吗,其中存储的是地址吗?

#include <iostream>
#include <list>
#include <cstdio>

typedef struct st
{
    int m;
    int n;
}st_t;

int main (int argc, char *argv[])
{
    int *_i1, *_i2;
    st_t *pST;
    std::list<st_t> stList;
    std::list<st_t>::iterator iterSTList;
    st_t varST;
    varST.m = 1;
    varST.n = 10;
    stList.push_back(varST);
    varST.m = 2;
    varST.n = 20;
    stList.push_back(varST);

    for (iterSTList=stList.begin(); iterSTList!=stList.end(); iterSTList++)
    {
        pST = iterSTList;
        pST = &(*iterSTList);
        std::cout << " iterSTList " << iterSTList << std::endl
                  << " pST->m " << pST->m << std::endl
                  << " pST->n " << pST->n << std::endl
                  << " (*pST).m " << (*pST).m << std::endl
                  << " (*pST).n " << (*pST).n << std::endl;
                  << " pST " << pST << std::endl
                  << " &(*iterSTList) " << &(*iterSTList) << std::endl;

        printf("iterSTList %X \n", iterSTList);

        _i1 = &(iterSTList->m);
        _i2 = &(iterSTList->n);     
        std::cout << " _i1 " << _i1  << " iterSTList->m " << iterSTList->m << std::endl
                  << " *_i1 " << *_i1  << " (*iterSTList).m " << (*iterSTList).m << std::endl
                  << " _i2 " << _i2  << " iterSTList->n" << iterSTList->n << std::endl
                  << " *_i2 " << *_i2  << " (*iterSTList).n " << (*iterSTList).n << std::endl;

    }

    return 0;
}

此时的错误为:

main.cpp(27) : error C2679: binary '=' : no operator defined which takes a right-hand operand of type 'class std::list<struct st,class std::allocator<struct st> >::iterator' (or there is no acceptable conversion)

说明 iterSTList 是一个 std::list

main.cpp(29) : error C2679: binary '<<' : no operator defined which takes a right-hand operand of type 'class std::list<struct st,class std::allocator<struct st> >::iterator' (or there is no acceptable conversion)

iterSTList 不能使用 cout 输出,因为没有定义 << 操作。那么这里只有尝试用 printf() 以十六进制形式打印其值。

将这两条操作注释掉后,事实上, pST = &(*iterSTList); 是赋值成功的。并且从打印结果,可以看出 pST 指向了 List 中的结构体元素。

pST->m 1

pST->n 10

(*pST).m 1

(*pST).n 10

pST 00773748

&(*iterSTList) 00773748

iterSTList 773740

_i1 00773748 iterSTList->m 1

*_i1 1 (*iterSTList).m 1

_i2 0077374C iterSTList->n10

*_i2 10 (*iterSTList).n 10

pST->m 2

pST->n 20

(*pST).m 2

(*pST).n 20

pST 00770850

&(*iterSTList) 00770850

iterSTList 770848

_i1 00770850 iterSTList->m 2

*_i1 2 (*iterSTList).m 2

_i2 00770854 iterSTList->n20

*_i2 20 (*iterSTList).n 20

Press any key to continue

iterSTList 的值与 &(*iterSTList) 值不相同,iterSTList 却能以指针的方式访问元素。&(*iterSTList) 与 _i1的值相同即 &(iterSTList->m) 相同。这个却是不解?地址不同却能取到相同的元素。

总之:取结构体元素可以 (*iterSTList).m 和 iterSTList->m 的方式。

非结构体的情况:

#include <iostream>
#include <list>
#include <cstdio>

int main (int argc, char *argv[])
{
    int *_i1, *_i2;
    int *p;
    std::list<int> iList;
    std::list<int>::iterator iter;
    int m;
    m = 1;
    iList.push_back(m);
    m = 2;
    iList.push_back(m);

    for (iter=iList.begin(); iter!=iList.end(); iter++)
    {
        p = iter;
        p = &(*iter);
        std::cout << " iter " << iter << std::endl
                  << " p " << p << std::endl
                  << " &(*iter) " << &(*iter) << std::endl;

        printf("iter %X \n", iter);

    }

    return 0;
}

同样的错误:iter 没有 = 和 << 操作。

main.cpp(19) : error C2679: binary '=' : no operator defined which takes a right-hand operand of type 'class std::list<int,class std::allocator<int> >::iterator' (or there is no acceptable conversion)
main.cpp(21) : error C2679: binary '<<' : no operator defined which takes a right-hand operand of type 'class std::list<int,class std::allocator<int> >::iterator' (or there is no acceptable conversion)

结果:

p 002D3738 *p 1

&(*iter) 002D3738 *iter 1

iter 2D3730

p 002D3770 *p 2

&(*iter) 002D3770 *iter 2

iter 2D3768

Press any key to continue

iter 的值 和 &(*iter) 即 p 的值依然不一样, *iter 却与*p取到的值一样。

总之:取元素使用 *iter

更多讨论:


what-list-iterator-exactly-is-in-cplusplus-stl

iterator 并不是一个指针,它提供 * , -> 等运算符的重载,所以可以类似地像指针一样取元素。

参考

stl_iterator.h


stl_list.h



版权声明:本文为ppdouble原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。