V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
mhjyzs
V2EX  ›  问与答

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

  •  
  •   mhjyzs · Mar 24, 2017 · 3586 views
    This topic created in 3321 days ago, the information mentioned may be changed or developed.

    一个 pointer 是一个 iterator 吗?

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