0

When passing an rvalue reference (Movable&& a) to a function, Movable b(a) somehow triggers the deleted copy constructor.

main.cpp: In function 'void func(Movable&&)': main.cpp:25:16: error: use of deleted function 'Movable::Movable(const Movable&)' Movable b(a);

but Movable b(std::move(a)) works. From reading

template< class T >
typename std::remove_reference<T>::type&& move( T&& t ) noexcept;

I don't understand the difference between Movable&& a and std::move(a). Below is a minimal working example.

#include<memory>

class Movable {
public:
    Movable() = default;

    Movable(const Movable&) = delete;
    Movable& operator=(const Movable&) = delete;

    Movable(Movable&& o) {}
};


void func(Movable&& a) {
  Movable b(std::move(a)); // this works
  // Movable b(a); // this doesn't compile
}

int main() {
    Movable A;
    func(std::move(A));
}
Ron
  • 14,674
  • 4
  • 34
  • 47
qweruiop
  • 3,156
  • 6
  • 31
  • 55
  • 2
    An rvalue reference is not itself an rvalue. – François Andrieux Mar 08 '18 at 18:17
  • @FrançoisAndrieux But isn't a rvalue reference all what's needed to call `Movable(Movable&& o)`? Why does `Movable&&` has to be matched with a rvalue? – qweruiop Mar 08 '18 at 18:50
  • 1
    No, a named rvalue reference is not an rvalue and can't be bound to another rvalue reference. For example, if you have a `int && x;` you can't do `int && y = x;` because `x` refers to an rvalue but isn't itself an rvalue. Though I see how it could be unintuitive. – François Andrieux Mar 08 '18 at 18:59
  • @FrançoisAndrieux Yeah I guess I don't understand the restriction of binding. So only a __rvalue__ rvalue reference can be bound to a rvalue reference? Could you give some intuition? – qweruiop Mar 08 '18 at 19:20
  • Only an rvalue can be bound to an rvalue reference. ravlue references are generally useless except as parameter types, where they are useful because they impose restrictions on the types of arguments taken, communicate the intent of the function and participates in function overload resolution. From within the body of those functions, they behave mostly like any other type of reference. You always need to std::move a named rvalue reference again, or the referred object's members, if you want to take advantage of it's rvalue-ness. Otherwise rvalue references are useful for communicating intent. – François Andrieux Mar 08 '18 at 19:37

0 Answers0