Hello,请问标准是否有保证 std::map 的 move constructor 后 other 为空? - V2EX
wutiantong
V2EX    C

Hello,请问标准是否有保证 std::map 的 move constructor 后 other 为空?

  •  
  •   wutiantong Jul 8, 2019 2995 views
    This topic created in 2502 days ago, the information mentioned may be changed or developed.
    map( map&& other )
    12 replies    2019-07-10 15:23:26 +08:00
    blinue
        1
    blinue  
       Jul 8, 2019 via Android
    没有。移动构造后 other 处于某个合法但不确定的状态,不保证为空,取决于具体实现
    wutiantong
        2
    wutiantong  
    OP
       Jul 8, 2019
    @blinue 如果是 vector,other 是会为空的,cppreference 上有提到这点; https://stackoverflow.com/a/17735913/6947776 这里有更详细的解释:
    This operation must have constant complexity ...So for the move constructor, yes, the moved-from vector will always be empty. This is not directly specified, but falls out of the complexity requirement, and the fact that there is no other way to implement it.

    而 map 的相关信息不多,cppreference 也没提到 other 是否为空的事情,但有复杂度的条款:
    Constant. If alloc is given and alloc != other.get_allocator(), then linear.

    所以我很好奇这里会不会也和 vector 有类似的情况。
    bumz
        3
    bumz  
       Jul 8, 2019 via iPhone
    并不是,我不一定要 move 之后为空
    因为标准没说 move 之后的容器应该啥样,只说你不该用它

    我直接把它加一个 flag 叫 invalid,析构的时候跳过
    其他方法并不检查 invalid,这也符合标准

    所以任何标准没说的东西,为了可移植性,原则上不应当依赖。
    bumz
        4
    bumz  
       Jul 8, 2019 via iPhone
    @bumz 更正,这个 flag 不应该叫 invalid
    叫 moved 就行
    然后规定 moved 对象你不能用,只能等他析构

    这也符合标准,因为标准没规定 move 之后需要处在什么状态

    “ valid but unspecifiedl ”
    bumz
        5
    bumz  
       Jul 8, 2019 via iPhone
    @bumz 准确的说任何需要 precondition 的操作,都不能在 moved 对象上用,但是你完全可以给他一个新的值
    wutiantong
        6
    wutiantong  
    OP
       Jul 8, 2019
    @bumz 我问的是 special case,而不是 general case,你应该看看我在前面放的一些描述和引用。
    lrxiao
        7
    lrxiao  
       Jul 8, 2019
    这个 SO 回答有问题... constant time 没有任何隐含 moved 就会 empty 的关系...如果标准使得必须 empty,那也不是有意为之
    wutiantong
        8
    wutiantong  
    OP
       Jul 9, 2019
    @lrxiao 我没懂你后半句。然后我还是觉得这个 SO 回答得蛮靠谱的,你所说的“ constant time 没有任何隐含 moved 就会 empty 的关系.” 能否进一步解释一下?或者给个例子论证一下呢?
    hxy1ng
        9
    hxy1ng  
       Jul 9, 2019 via iPhone
    这个答案有问题吧,他可能想当然的认为

    this->data = other.data;
    other.data = nullptr;

    但是没有人规定要把 other.data 设成 nullptr。如果你担心析构时的问题,一般确实是这样写的:

    if (this->data) delete[] this->data;

    但是我完全可以自己加一个私有变量 bool

    if (!moved) delete[] this->data;
    wutiantong
        10
    wutiantong  
    OP
       Jul 9, 2019
    不想再继续解释了,希望有真正了解 standard 的同学来回答一下。
    bumz
        11
    bumz  
       Jul 10, 2019 via iPhone
    @wutiantong 那个回答是错的

    同样类比这个逻辑到 map 也是错的

    了解 standard 就是知道标准没规定什么,所以为了可移植不应该依赖什么

    过度解读不叫了解标准

    你要是想要把你目前用的实现当标准,不要可移植性,就去看它的源代码
    wutiantong
        12
    wutiantong  
    OP
       Jul 10, 2019
    @bumz 即便那个回答里相关的因果关系是错的,但我所关心的其实是“ vector move constructor make other empty ”这个结论,你可以看一下 https://en.cppreference.com/w/cpp/container/vector/vector 其中明确提到:

    After the move, other is guaranteed to be empty().

    当然我也知道 cppreference 并不代表 C++标准,但它的准确度还是很高的。那么:

    1 )如果你觉得这一条是符合标准的;那能否顺手给我指引一下出处,如果能进一步指出与 map 情况相关的出处就更感谢了。
    2 )如果你有充分的理由觉得这一条是杜撰的,不存在的;那你也许可以做点儿好事,给 cppreference 提个 issue,给那个 SO 回答加一条 comment。
    About     Help     Advertise     Blog     API     FAQ     Solana     4012 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 233ms UTC 05:06 PVG 13:06 LAX 22:06 JFK 01: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