简体   繁体   中英

what does std::move(const shared_ptr reference) mean?

The following is toy code I am trying... I understand the first and second one. The first one give the ownership to _p . The second one copies p to _p . but I don't understand the third one...

What does std::move of const shared_ptr & mean? Thank you.

class P { };

class A {
public:
    // first one
    A(std::shared_ptr<P> &p, int) : _p(std::move(p))
    {
        std::cout << "1st Ctor: "
                  << p.use_count() << ", " << _p.use_count() << std::endl;
    }

    // second one
    A(const std::shared_ptr<P> &p, std::string) : _p(p)
    {
        std::cout << "2nd Ctor: "
                  << p.use_count() << ", " << _p.use_count() << std::endl;
    }

    // third one
    A(const std::shared_ptr<P> &p) : _p(std::move(p))
    {
        std::cout << "3rd Ctor: "
                  << p.use_count() << ", " << _p.use_count() << std::endl;
    }

private:
    std::shared_ptr<P> _p;
};

int main()
{
    {
        std::shared_ptr<P> p = std::make_shared<P>();
        A a(p, 1);
        std::cout << "1. body: " << p.use_count() << std::endl;
    }
    std::cout << "-------------" << std::endl;
    {
        std::shared_ptr<P> p = std::make_shared<P>();
        A a(p, "2");
        std::cout << "2. body: " << p.use_count() << std::endl;
    }
    std::cout << "-------------" << std::endl;
    {
        std::shared_ptr<P> p = std::make_shared<P>();
        A a(p);
        std::cout << "3. body: " << p.use_count() << std::endl;
    }
 }

Result is:

$ ./a.out 
1st Ctor: 0, 1
1. body: 0
-------------
2nd Ctor: 2, 2
2. body: 2
-------------
3rd Ctor: 2, 2
3. body: 2

(updated: adding comment to clarify which one is first one, second one, etc.)

std::move just performs conversion and produces xvalue (rvalue).

When being passed a const std::shared_ptr<P> , its return type would be const std::shared_ptr<P>&& . Then for _p(std::move(p)) the copy constructor of std::shared_ptr (but not move constructor which taking rvalue-reference to non-const ) will be called, the effect is just same as the 2nd case.

Basically move operation tends to perform modification on the object being moved; it's not supposed to work on const objects.

std::move is a function which converts the argument to an rvalue reference. The function call is an xvalue expression.

When the argument is a reference to const, then the result of the conversion is an rvalue to const. If you initialise from rvalue to const, copy constructor will be used because the rvalue reference parameter to non-const of the move constructor cannot bind to rvalue reference argument to const.

I think there is also an implicit question by OP of how _p(std::move(p)) might differ from _p(p)

_p(std::move(p)) doesn't differ from _p(p) in case of const std::shared_ptr<T> .

In theory, if decltype(_p) was a type that had a constructor T(const T&&) , then there would be a difference, since that constructor would be invoked by _p(std::move(p)) but not by _p(p) . Such constructor would be quite unconventional, but technically well-formed. std::shared_ptr doesn't have such constructor.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM