0

I am currently trying to understand the copy and swap idiom through this post. The answer posted has the following code in it

class dumb_array
{
public:
    // ...

    friend void swap(dumb_array& first, dumb_array& second) // nothrow
    {
        // enable ADL (not necessary in our case, but good practice)
        using std::swap; 

        // by swapping the members of two classes,
        // the two classes are effectively swapped
        swap(first.mSize, second.mSize); 
        swap(first.mArray, second.mArray);
    }

    // move constructor
    dumb_array(dumb_array&& other)
        : dumb_array() // initialize via default constructor, C++11 only
    {
        swap(*this, other); //<------Question about this statement
    }

    // ...
};

I noticed that the author used this statement

swap(*this, other);

other is a temporary or a rvalue which is being passed as a reference to the method swap. I was not sure if we could pass a rvalue by reference. In order to test this I tried doing this however the following does not work until i convert the parameter to a const reference

void myfunct(std::string& f)
{
    std::cout << "Hello";
}

int main() 
{
   myfunct(std::string("dsdsd"));
}

My question is how can other being a temporary be passed by reference in swap(*this, other); while myfunct(std::string("dsdsd")); cant be passed by reference.

Community
  • 1
  • 1
Rajeshwar
  • 11,179
  • 26
  • 86
  • 158
  • 1
    I think you need to understand what an rvalue reference is: http://stackoverflow.com/a/5481588/4342498 – NathanOliver Mar 31 '15 at 19:08
  • 1
    `swap(*this, other);` is wrong. It has to be `swap(*this, std::move(other));` (other is a named variable) –  Mar 31 '15 at 19:12
  • @DieterLücking in that case swap method wont work as it requires a reference and you are passing a temporary. It would only work as you suggested if it was a constant reference. Please correct me if i am wrong – Rajeshwar Mar 31 '15 at 19:13
  • Please have a look at : http://en.cppreference.com/w/cpp/language/value_category –  Mar 31 '15 at 19:24
  • @DieterLücking Why do you think `swap` would expect an rvalue argument? – T.C. Apr 01 '15 at 07:38

2 Answers2

7

The constructor takes a rvalue reference, but other is a lvalue (it has a name).

Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • Yes that makes sense. So other basically holds an rvalue but is itself an lvalue. Am i correct ? – Rajeshwar Mar 31 '15 at 19:10
  • @Rajeshwar: I think it's slightly more accurate to say the reference is an lvalue that is _constructed from_ an rvalue. (references aren't truely "constructed", but you get the idea) – Mooing Duck Mar 31 '15 at 19:41
0

In the case of:

myfunct(std::string("dsdsd"));

The value std::string("dsdsd") is a temporary within a scope that the call to myfunct() is actually outside of.

C++ explicitly specifies that binding the reference to const extends the lifetime of the temporary to the lifetime of the reference itself.

Nilzone-
  • 2,766
  • 6
  • 35
  • 71
Adam Leggett
  • 3,714
  • 30
  • 24