在 C++中 pointer 与 iterator 的区别是什么? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
mhjyzs

在 C++中 pointer 与 iterator 的区别是什么?

  •  
  •   mhjyzs 2017 年 3 月 24 日 3579 次点击
    这是一个创建于 3318 天前的主题,其中的信息可能已经有所发展或是发生改变。

    一个 pointer 是一个 iterator 吗?

    32 条回复    2017-03-25 16:50:53 +08:00
    pagict
        1
    pagict  
       2017 年 3 月 24 日
    我理解为 iterator 是 pointer 的 wrapper , iterator 可 next(), 可边界检查 etc
    sagaxu
        2
    sagaxu  
       2017 年 3 月 24 日
    完全不相似的两个东西,也能比较出区别来?
    mhjyzs
        3
    mhjyzs  
    OP
       2017 年 3 月 24 日 via Android
    @sagaxu 请说出你的理由!?
    sagaxu
        4
    sagaxu  
       2017 年 3 月 24 日
    @mhjyzs pointer 是对虚拟内存地址的寻址,迭代器是一种遍历访问接口,毫不相干。你觉得这两者有相同点?
    htfy96
        5
    htfy96  
       2017 年 3 月 24   2
    iterator 是一个概念,指的是一类类型,只要支持++, *等操作的类型都能被称为 iterator: http://en.cppreference.com/w/cpp/concept/Iterator
    一般所说 pointer 基本满足 iterator 的要求
    HenryKCU
        6
    HenryKCU  
       2017 年 3 月 24 日 via Android
    就好像火药和炸药的区别,完全不是一个东西
    mhjyzs
        7
    mhjyzs  
    OP
       2017 年 3 月 24 日
    @htfy96 意思是 pointer 是一个 iterator, 但是 iterator 是一个更大的概念。
    nicevar
        8
    nicevar  
       2017 年 3 月 25 日
    @mhjyzs 上面的兄弟白跟你解释了啊,简单点理解指针就是一个内存地址,内存地址你总知道了吧,真的是与 iterator 没啥关系
    wwqgtxx
        9
    wwqgtxx  
       2017 年 3 月 25 日 via iPhone
    pointer 是一个基础类型
    iterator 是一个重载了运算符的类
    这就是他们最大的区别
    lcdtyph
        10
    lcdtyph  
       2017 年 3 月 25 日 via Android
    迭代器是指针的泛化。
    kmyzzy
        11
    kmyzzy  
       2017 年 3 月 25 日 via Android
    这俩根本就没关系
    mhjyzs
        12
    mhjyzs  
    OP
       2017 年 3 月 25 日
    @lcdtyph 嗯嗯,我比较同意这个说法.
    mhjyzs
        13
    mhjyzs  
    OP
       2017 年 3 月 25 日
    @HenryKCU 你确定火药和炸药完全不是一个东西?
    j5shi
        14
    j5shi  
       2017 年 3 月 25 日 via iPhone
    @HenryKCU 所以火药不能当炸药?
    htfy96
        15
    htfy96  
       2017 年 3 月 25 日 via Android   1
    @nicevar @wwqgtxx 重复一下, iterator 和重没重载运算符、底层是啥真没关系,只要满足操作就行。所以普通的 pointer 也是 iterator ,一个例子就是 std::find 这类标准库算法也能接受指针作为输入
    wwqgtxx
        16
    wwqgtxx  
       2017 年 3 月 25 日 via iPhone
    @htfy96 那就看你怎么理解了,从面向对象的角度考虑,指针并不是一个 iterator ,因为 pointer 不是 iterator 的子类,不过你要是从范化的概念上说,也可以这么理解
    mhjyzs
        17
    mhjyzs  
    OP
       2017 年 3 月 25 日
    @htfy96 @nicevar 我也是看见 remove_copy_if 这个前两个参数是接受 iterator,但是传入 pointer 也是正确的,所以我才疑惑 pointer 是不是一个 iterator .可以看这 http://www.cplusplus.com/reference/algorithm/remove_copy_if/?kw=remove_copy_if
    htfy96
        18
    htfy96  
       2017 年 3 月 25 日 via Android
    @wwqgtxx C++在这块是 duck typing ,不需要显式继承某个接口
    radiolover
        19
    radiolover  
       2017 年 3 月 25 日
    iterator 是类,有一个指针成员,所以 sizeof(pointer) = sizeof(iterator object)
    iterator 重载了++,*等操作,所以行为看上去像指针。
    wwqgtxx
        20
    wwqgtxx  
       2017 年 3 月 25 日 via iPhone
    @htfy96 那其实也是用模板来范化而已,从概念上说,个人还是喜欢严格的继承型接口,不过对于 c++这种静态语言的确差异不大, golang 的接口也是这么干的,只不过他才是真正的 duck typing ,因为他的接受类型是一个真真正正的 interface ,而不是没有约束的模板
    htfy96
        21
    htfy96  
       2017 年 3 月 25 日 via Android
    @wwqgtxx 其实 C++也可以用 SFINAE 等奇怪的技巧来约束类型…要是 concept 进 C++20 了就能用类似的语法了
    starvedcat
        22
    starvedcat  
       2017 年 3 月 25 日
    问:火车和汽车有什么区别?
    答:这两种东西完全没关系!(有什么区别?不告诉你,呵呵)
    nicevar
        23
    nicevar  
       2017 年 3 月 25 日
    @mhjyzs 我看大家再解释下去你更晕了, iterator 用起来像指针,但是操作不是指针操作,它是个 object ,它那些操作都是通过重载实现的,你要真认为 iterator 是指针的话,用 c 语言的观点来强行看就是了
    SuperFashi
        24
    SuperFashi  
       2017 年 3 月 25 日 via Android   1
    iterator 是 pointer 的超集, pointer 是一种 random iterator 。
    mhjyzs
        25
    mhjyzs  
    OP
       2017 年 3 月 25 日
    @nicevar 我是认为 pointer 是一个 iterator.
    k9982874
        26
    k9982874  
       2017 年 3 月 25 日 via iPad
    9 楼 10 楼正解。举个不恰当但是能说明问题的例子 java 中的 int 和 integer 。
    FrankHB
        27
    FrankHB  
       2017 年 3 月 25 日   2
    C++所谓的 pointer 可以有多种含义。
    一类是从 C 照搬的 pointer ,是一类内建类型。
    另一类是库中约定的泛化的 pointer ,如满足标准 NullablePointer requirements 的类型(例如 unique_ptr 的实例)。这些类型往往也被直接称为 pointer ,如 smart pointer 。严格来说这些类型只是 pointer-like ,限制比内建 pointer 小,除了 CopyConstructible 之类的语义约定外,通常只要求特定的*或->操作之一(连这些操作都没有的一般称为 handler )。
    iterator 是指库(如 SGI 或标准库)约定的概念,一般指满足标准 Iterator requirements 的类型。这对右值 r 只要求*r 和++r ,限制同样比无论哪种 pointer 都小得多。
    在标准库的框架中,内建的 pointer 是 random access iterator ,然后可以很容易推出 pointer 是 iterator :
    random access iterator 是 bidirectional iterator ;
    bidirectional iterator 是 forward iterator ;
    forward iterator 是 input iterator ;
    input iterator 是 iterator 。
    Q.E.D.
    反过来不成立。
    至于其它意义上的 pointer ,连++都不保证有,就自然不是 iterator 了。

    @pagict 看清楚标题。
    C++的 iterator 哪来的 next()。
    @sagaxu 关虚拟地址毛线?
    unique_ptr 跟地址有一腿?
    逻辑地址和物理地址就不能跟 pointer 有一腿?
    @nicevar 哪个语言的指针是所谓的内存地址?
    FrankHB
        28
    FrankHB  
       2017 年 3 月 25 日   1
    @htfy96 不要看上去 duck 就 duck 了。 Duck typing 是把类型检查推迟到运行时,而 C++这里明显不是。这叫 structural typing ,对立的是 nominal typing 。
    @wwqgtxx golang 那也是 structural typing ,而且用户无法自主编码类型检查规则。
    @starvedcat 火焰猫是一只火车然而不是汽车……(
    wwqgtxx
        29
    wwqgtxx  
       2017 年 3 月 25 日 via iPhone
    @FrankHB 谁说 golang 不可以自主编码类型检测规则的,你直接用反射检测一下不就行了
    FrankHB
        30
    FrankHB  
       2017 年 3 月 25 日
    @wwqgtxx 用 reflection 实现 type introspection 编码的可不是 typechecking rules 。
    mhjyzs
        31
    mhjyzs  
    OP
       2017 年 3 月 25 日
    @FrankHB 谢谢解释得这么清楚.
    sagaxu
        32
    sagaxu  
       2017 年 3 月 25 日 via Android
    @FrankHB 泛化的讲也没错, smart pointer 也算 pointer 的一种。 raw pointer ,在常见平台上,还是对应到虚拟地址空间的,不然 mmap 这样的地址映射是没法实现的。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2779 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 70ms UTC 01:06 PVG 09:06 LAX 18:06 JFK 21:06
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86