V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
mhjyzs
V2EX  ›  问与答

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

  •  
  •   mhjyzs · 2017-03-24 22:12:06 +08:00 · 3179 次点击
    这是一个创建于 2802 天前的主题,其中的信息可能已经有所发展或是发生改变。

    一个 pointer 是一个 iterator 吗?

    32 条回复    2017-03-25 16:50:53 +08:00
    pagict
        1
    pagict  
       2017-03-24 22:48:10 +08:00
    我理解为 iterator 是 pointer 的 wrapper , iterator 可 next(), 可边界检查 etc
    sagaxu
        2
    sagaxu  
       2017-03-24 22:57:44 +08:00
    完全不相似的两个东西,也能比较出区别来?
    mhjyzs
        3
    mhjyzs  
    OP
       2017-03-24 23:05:03 +08:00 via Android
    @sagaxu 请说出你的理由!?
    sagaxu
        4
    sagaxu  
       2017-03-24 23:12:50 +08:00
    @mhjyzs pointer 是对虚拟内存地址的寻址,迭代器是一种遍历访问接口,毫不相干。你觉得这两者有相同点?
    htfy96
        5
    htfy96  
       2017-03-24 23:13:30 +08:00   ❤️ 2
    iterator 是一个概念,指的是一类类型,只要支持++, *等操作的类型都能被称为 iterator: http://en.cppreference.com/w/cpp/concept/Iterator
    一般所说 pointer 基本满足 iterator 的要求
    HenryKCU
        6
    HenryKCU  
       2017-03-24 23:29:54 +08:00 via Android
    就好像火药和炸药的区别,完全不是一个东西
    mhjyzs
        7
    mhjyzs  
    OP
       2017-03-24 23:56:44 +08:00
    @htfy96 意思是 pointer 是一个 iterator, 但是 iterator 是一个更大的概念。
    nicevar
        8
    nicevar  
       2017-03-25 00:02:09 +08:00
    @mhjyzs 上面的兄弟白跟你解释了啊,简单点理解指针就是一个内存地址,内存地址你总知道了吧,真的是与 iterator 没啥关系
    wwqgtxx
        9
    wwqgtxx  
       2017-03-25 00:15:27 +08:00 via iPhone
    pointer 是一个基础类型
    iterator 是一个重载了运算符的类
    这就是他们最大的区别
    lcdtyph
        10
    lcdtyph  
       2017-03-25 00:23:16 +08:00 via Android
    迭代器是指针的泛化。
    kmyzzy
        11
    kmyzzy  
       2017-03-25 00:34:49 +08:00 via Android
    这俩根本就没关系
    mhjyzs
        12
    mhjyzs  
    OP
       2017-03-25 08:25:18 +08:00
    @lcdtyph 嗯嗯,我比较同意这个说法.
    mhjyzs
        13
    mhjyzs  
    OP
       2017-03-25 08:29:45 +08:00
    @HenryKCU 你确定火药和炸药完全不是一个东西?
    j5shi
        14
    j5shi  
       2017-03-25 08:50:14 +08:00 via iPhone
    @HenryKCU 所以火药不能当炸药?
    htfy96
        15
    htfy96  
       2017-03-25 08:55:52 +08:00 via Android   ❤️ 1
    @nicevar @wwqgtxx 重复一下, iterator 和重没重载运算符、底层是啥真没关系,只要满足操作就行。所以普通的 pointer 也是 iterator ,一个例子就是 std::find 这类标准库算法也能接受指针作为输入
    wwqgtxx
        16
    wwqgtxx  
       2017-03-25 09:08:21 +08:00 via iPhone
    @htfy96 那就看你怎么理解了,从面向对象的角度考虑,指针并不是一个 iterator ,因为 pointer 不是 iterator 的子类,不过你要是从范化的概念上说,也可以这么理解
    mhjyzs
        17
    mhjyzs  
    OP
       2017-03-25 09:08:45 +08:00
    @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-03-25 09:28:29 +08:00 via Android
    @wwqgtxx C++在这块是 duck typing ,不需要显式继承某个接口
    radiolover
        19
    radiolover  
       2017-03-25 09:33:27 +08:00
    iterator 是类,有一个指针成员,所以 sizeof(pointer) = sizeof(iterator object)
    iterator 重载了++,*等操作,所以行为看上去像指针。
    wwqgtxx
        20
    wwqgtxx  
       2017-03-25 09:35:12 +08:00 via iPhone
    @htfy96 那其实也是用模板来范化而已,从概念上说,个人还是喜欢严格的继承型接口,不过对于 c++这种静态语言的确差异不大, golang 的接口也是这么干的,只不过他才是真正的 duck typing ,因为他的接受类型是一个真真正正的 interface ,而不是没有约束的模板
    htfy96
        21
    htfy96  
       2017-03-25 09:54:02 +08:00 via Android
    @wwqgtxx 其实 C++也可以用 SFINAE 等奇怪的技巧来约束类型…要是 concept 进 C++20 了就能用类似的语法了
    starvedcat
        22
    starvedcat  
       2017-03-25 10:08:50 +08:00
    问:火车和汽车有什么区别?
    答:这两种东西完全没关系!(有什么区别?不告诉你,呵呵)
    nicevar
        23
    nicevar  
       2017-03-25 10:37:09 +08:00
    @mhjyzs 我看大家再解释下去你更晕了, iterator 用起来像指针,但是操作不是指针操作,它是个 object ,它那些操作都是通过重载实现的,你要真认为 iterator 是指针的话,用 c 语言的观点来强行看就是了
    SuperFashi
        24
    SuperFashi  
       2017-03-25 10:51:50 +08:00 via Android   ❤️ 1
    iterator 是 pointer 的超集, pointer 是一种 random iterator 。
    mhjyzs
        25
    mhjyzs  
    OP
       2017-03-25 11:01:19 +08:00
    @nicevar 我是认为 pointer 是一个 iterator.
    k9982874
        26
    k9982874  
       2017-03-25 12:24:57 +08:00 via iPad
    9 楼 10 楼正解。举个不恰当但是能说明问题的例子 java 中的 int 和 integer 。
    FrankHB
        27
    FrankHB  
       2017-03-25 13:18:08 +08:00   ❤️ 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-03-25 13:29:09 +08:00   ❤️ 1
    @htfy96 不要看上去 duck 就 duck 了。 Duck typing 是把类型检查推迟到运行时,而 C++这里明显不是。这叫 structural typing ,对立的是 nominal typing 。
    @wwqgtxx golang 那也是 structural typing ,而且用户无法自主编码类型检查规则。
    @starvedcat 火焰猫燐是一只火车然而不是汽车……(
    wwqgtxx
        29
    wwqgtxx  
       2017-03-25 13:41:12 +08:00 via iPhone
    @FrankHB 谁说 golang 不可以自主编码类型检测规则的,你直接用反射检测一下不就行了
    FrankHB
        30
    FrankHB  
       2017-03-25 13:52:47 +08:00
    @wwqgtxx 用 reflection 实现 type introspection 编码的可不是 typechecking rules 。
    mhjyzs
        31
    mhjyzs  
    OP
       2017-03-25 14:10:38 +08:00
    @FrankHB 谢谢解释得这么清楚.
    sagaxu
        32
    sagaxu  
       2017-03-25 16:50:53 +08:00 via Android
    @FrankHB 泛化的讲也没错, smart pointer 也算 pointer 的一种。 raw pointer ,在常见平台上,还是对应到虚拟地址空间的,不然 mmap 这样的地址映射是没法实现的。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5992 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 03:12 · PVG 11:12 · LAX 19:12 · JFK 22:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.