Search code examples
c++11shared-ptrmove-semanticsstd

C++: For which objects, being "moved" implies more than "staying valid"?


Given that a and b are of type T, and we have either move construction (T b(move(a));) or move assignment (b = move(a)). In what cases do we know what the value of a will be?

The only one that I know of for sure is unique_ptr, in which a will become an empty pointer. Is this also guaranteed for shared_ptr? Are there any other classes for which the standard guarantees a known value?


Solution

  • Standard library types

    From the standard N4296,§17.6.3.1, let's rv be an rvalue of type T, in Table 20, MoveConstructible requirement and Table 22 MoveAssignable requirement.

    After operations:

    T(rv);
    T u =rv;
    u = rv;
    

    rv’s state is unspecified [ Note:rv must still meet the requirements of the library component that is using it. The operations listed in those requirements must work as specified whether rv has been moved from or not. — end note ]

    It means that at least your moved object is still in a valid state and can be used as any object of its type. But nothing more is required as a library wide requirement. You have to read specific documentation.

    For shared_ptr specificaly :

    shared_ptr(shared_ptr&& r) noexcept;
    template<class Y> shared_ptr(shared_ptr<Y>&& r) noexcept;
    

    Remark: The second constructor shall not participate in overload resolution unless Y* is convertible to T*.

    Effects: Move-constructs a shared_ptr instance from r. Postconditions: *this shall contain the old value of r. r shall be empty. r.get() == nullptr.

    Fundamental types and trivially copyables

    The moved object should be unchanged. I am looking for the confirmation in the standard...

    Other types

    At least the programmer of a class shall ensures that an object of this class is destructible after it has been moved!