简体   繁体   中英

What is point of passing rvalue reference to class constructor?

Ok

So I have a class, MyClass. I would like to construct this class with say a vector of ints. I want to move this vector into the object. The class is not templated.

class Myclass {
     public:
     Myclass (std::vector<int> && in) : vec{in} {};
     Myclass (std::vector<int> & in) : vec{in} {};

    private:
    std::vector<int> vec;
    }

In my main I have

std::vector<int> orig (100);
Myclass A {orig};
std::cout << A.size() << '\n';

I want "orig" to be empty after moving it into "A". That does not happen in either of the options above. Even if I do

    std::vector<int> orig (100);
    Myclass A {std::move(orig)};
    std::cout << A.size() << '\n';  // still prints 100

It looks like I can achieve it via

 Myclass (std::vector<int> && in) : vec{std::move(in)} {};   // (1)

OR

 Myclass (std::vector<int> & in) : vec{std::move(in)} {};    // (2)

OR

Myclass (std::vector<int> && in) : vec{std::forward<std::vector<int>(in)} {};    // (3)

My question is why does (1) appear to behave exactly like (2)?

The thing to remember about references, rvalue and lvalue, is that they are lvalues. That means if you have a reference to a thing, that reference is an lvalue and you need std::move to cast it to an rvalue so it can be moved.

The real difference between Myclass (std::vector<int> && in) and Myclass (std::vector<int> & in) is that with the first you have to use

Myclass A {std::move(orig)};
// or
Myclass A {std::vector(100)};

and cant pass an lvalue to it, where as with second you can only uses

Myclass A {orig};

as it wont let you pass an rvalue to it.


Also note that constructor 3 is "incorrect". You should only use std::forward when you have a forwarding reference. std::vector<int> && in is a rvalue reference, not a forwarding one so you should use std::move instead. To use forward correctly you'd need a template constructor like

template <typename T, std::enable_if_t<
                                       std::is_same<std::decay_t<T>, 
                                       std::vector<int>>, bool> = true>
Myclass (T&& in) : vec{std::forward<T>(in)} {}; 

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