Are move semantics incomplete?

前端 未结 3 1114
暗喜
暗喜 2021-01-02 06:59

Move semantics replace copy semantics in situations where copying is inefficient. Copy semantics deals fully with copyable objects, including const objects.

Already,

相关标签:
3条回答
  • 2021-01-02 07:39

    Sorry, but the premise is flawed.

    An unordered_set doesn't actually hold const objects. It's just not giving you write access to the contained elements. That's a property of the accessors only.

    It would be possible to add an key erase(iterator) function which just moves the element out to a temporary. I'm not sure why you'd want a key&& there.

    As for const MyClass&& ~MyClass() const, that doesn't make sense for three reasons: dtors have neither return types nor CV classification, nor is overload resolution done for them.

    0 讨论(0)
  • 2021-01-02 07:52

    So basically you're saying it should be possible to move a const object into another const object and destroy the original?

    Sorry but I think the whole point of making it const is to prevent this.

    Otherwise it would form a loophole: you could destroy-move a const object out of its memory location, then you destroy-move another const object into the memory location of the first one (via placement new).

    Now the object has changed even though it was const... so essentially const was useless.

    See comments below...

    0 讨论(0)
  • 2021-01-02 07:59

    Imho you have identified a real need.

    Your solution sounds a lot like what I have called destructive move semantics. This possibility is described in the original move semantics proposal. I think such a design is possible, though it is not without its problems. As far as I know, no one is working this area on the standards committee.

    There are simpler ways to extract move-only types out of the associative containers that would not require language changes (aside maybe from allowing type-punning without undefined behavior).

    N3645 is a library-only proposal which puts a nested node_ptr type into each container. The node_ptr is a lot like a unique_ptr. It has unique ownership of a node in an associative container. But when you dereference it, you get non-const access to the value_type in the node, instead of the node itself. extract and insert members are added to the associative containers allowing one to insert and remove nodes (owned by the node_ptr) to/from the containers.

    You could use this to remove a node from a container, and then move a move-only type out of the node, and let ~node_ptr() clean up the node when you are done with it. The paper includes this example to demonstrate this functionality:

    set<move_only_type> s;
    s.emplace(...);
    move_only_type mot = move(*s.extract(s.begin())); // extract, move, deallocate node
    

    Note that s.extract is noexcept, as is ~node_ptr() of course. If the move construction of move_only_type is noexcept, then this whole operation is noexcept. Otherwise if the move construction throws, the set is left as if the item had been erased from the set.

    At the moment, no progress is being made on N3645. It has not been voted into a working draft, and I have no confidence that it ever will be.

    Update C++17

    I stand corrected: The functionality I describe above was voted into C++17 with P0083R3. Thanks to Cosme for reminding me of this in the comments below.

    0 讨论(0)
提交回复
热议问题