Wednesday, April 10, 2013

C++ 11 : lvalue, rValue and Move Constructor

Rvalue references are a feature of C++ that was added with the C++11 standard.
What makes rvalue references a bit difficult to grasp is that when you first look at
them, it is not clear what their purpose is or what problems they solve. Therefore, I
will not jump right in and explain what rvalue references are. Instead, I will start
with the problems that are to be solved and then show how rvalue references
provide the solution. That way, the definition of rvalue references will appear
plausible and natural to you.

Rvalue references solve at least two problems:
1. Implementing move semantics
2. Perfect forwarding

If you are not familiar with these problems, do not worry. Both of them will be
explained in detail below. We'll start with move semantics. But before we're ready
to go, I need to remind you of what lvalues and rvalues are in C++. Giving a
rigorous definition is surprisingly difficult, but the explanation below is good
enough for the purpose at hand.
The original definition of lvalues and rvalues from the earliest days of C is as
follows: An lvalue is an expression e that may appear on the left or on the right
hand side of an assignment, whereas an rvalue is an expression that can only
appear on the right hand side of an assignment. For example,

int a = 42;
int b = 43;
// a and b are both l-values:
a = b; // ok
b = a; // ok
a = a * b; // ok
// a * b is an rvalue:
int c = a * b; // ok, rvalue on right hand side of assignment
a * b = 42; // error, rvalue on left hand side of assignment


In C++, this is still useful as a first, intuitive approach to lvalues and rvalues.
However, C++ with its user-defined types has introduced some subtleties regarding
modifiability and assignability that cause this definition to be incorrect. There is no
need for us to go further into this. Here is an alternate definition which, although it
can still be argued with, will put you in a position to tackle rvalue references: An
lvalue is an expression that refers to a memory location and allows us to take the
address of that memory location via the & operator. An rvalue is an expression that
is not an lvalue. Every expression that is not an lvalue is an rvalue. Examples are:

// lvalues:
//
int i = 42;
i = 43; // ok, i is an lvalue
int* p = &i; // ok, i is an lvalue
int& foo();
foo() = 42; // ok, foo() is an lvalue
int* p1 = &foo(); // ok, foo() is an lvalue
// rvalues:
//
int foobar();
int j = 0;
j = foobar(); // ok, foobar() is an rvalue
int* p2 = &foobar(); // error, cannot take the address of an rvalue
j = 42; // ok, 42 is an rvalue


Move Semantics
Suppose X is a class that holds a pointer or handle to some resource, say, m_pResource.
By a resource, I mean anything that takes considerable effort to construct, clone, or
destruct. A good example is std::vector, which holds a collection of objects that live in an
array of allocated memory. Then, logically, the copy assignment operator for X looks like
this:

X& X::operator=(X const & rhs)
{
// [...]
// Destruct the resource that m_pResource refers to.
// Make a clone of what rhs.m_pResource refers to, and
// attach it to m_pResource.
// [...]
}


Similar reasoning applies to the copy constructor. Now suppose X is used as follows:

X foo();
X x;


// perhaps use x in various ways
x = foo();
The last line above
· destructs the resource held by x,
· clones the resource from the temporary returned by foo,
· destructs the temporary and thereby releases its resource.
Rather obviously, it would be ok, and much more efficient, to swap resource pointers
(handles) between x and the temporary, and then let the temporary's destructor destruct x's
original resource. In other words, in the special case where the right hand side of the
assignment is an rvalue, we want the copy assignment operator to act like this:
// [...]
// swap m_pResource and rhs.m_pResource
// [...]

This is called move semantics. With C++11, this conditional behavior can be achieved via
an overload:

X& X::operator=(<mystery type> rhs)
{
// [...]
// swap this->m_pResource and rhs.m_pResource
// [...]
}


Since we're defining an overload of the copy assignment operator, our "mystery type"
must essentially be a reference: we certainly want the right hand side to be passed to us
by reference. Moreover, we expect the following behavior of the mystery type: when
there is a choice between two overloads where one is an ordinary reference and the
other is the mystery type, then rvalues must prefer the mystery type, while lvalues must
prefer the ordinary reference.
If you now substitute "rvalue reference" for "mystery type" in the above, you're essentially
looking at the definition of rvalue references.
Rvalue References
If X is any type, then X&& is called an rvalue reference to X. For better distinction, the
ordinary reference X& is now also called an lvalue reference.
An rvalue reference is a type that behaves much like the ordinary reference X&, with
several exceptions. The most important one is that when it comes to function overload
resolution, lvalues prefer old-style lvalue references, whereas rvalues prefer the new
rvalue references:

void foo(X& x); // lvalue reference overload
void foo(X&& x); // rvalue reference overload
X x;
X foobar();
foo(x); // argument is lvalue: calls foo(X&)
foo(foobar()); // argument is rvalue: calls foo(X&&)


So the gist of it is:
Rvalue references allow a function to branch at compile time (via overload resolution) on
the condition "Am I being called on an lvalue or an rvalue?"
It is true that you can overload any function in this manner, as shown above. But in the
overwhelming majority of cases, this kind of overload should occur only for copy
constructors and assignment operators, for the purpose of achieving move semantics:

X& X::operator=(X const & rhs); // classical implementation
X& X::operator=(X&& rhs)
{
// Move semantics: exchange content between this and rhs
return *this;
}


Implementing an rvalue reference overload for the copy constructor is similar.
Caveat: As it happens so often in C++, what looks just right at first glance is still a little
shy of perfect. It turns out that in some cases, the simple exchange of content between
this and rhs in the implementation of the copy assignment operator above is not quite
good enough. We'll come back to this in Section 4, "Forcing Move Semantics" below.
Note: If you implement
void foo(X&);
but not
void foo(X&&);
then of course the behavior is unchanged: foo can be called on l-values, but not on rvalues.
If you implement
void foo(X const &);
but not
void foo(X&&);
then again, the behavior is unchanged: foo can be called on l-values and r-values, but it is
not possible to make it distinguish between l-values and r-values. That is possible only by
implementing
void foo(X&&);
as well. Finally, if you implement
void foo(X&&);
but neither one of
void foo(X&);
and
void foo(X const &);
then, according to the final version of C++11, foo can be called on r-values, but trying to
call it on an l-value will trigger a compile error.

Forcing Move Semantics

As we all know, the First Amendment to the C++ Standard states: "The committee shall
make no rule that prevents C++ programmers from shooting themselves in the foot."
Speaking less facetiously, when it comes to choosing between giving programmers more
control and saving them from their own carelessness, C++ tends to err on the side of
giving more control. Being true to that spirit, C++11 allows you to use move semantics
not just on rvalues, but, at your discretion, on lvalues as well. A good example is the std
library function swap. As before, let X be a class for which we have overloaded the copy
constructor and copy assignment operator to achieve move semantics on rvalues.
template<class T>
void swap(T& a, T& b)
{
T tmp(a);
a = b;
b = tmp;
}
X a, b;
swap(a, b);


There are no rvalues here. Hence, all three lines in swap use non-move semantics. But we
know that move semantics would be fine: wherever a variable occurs as the source of a
copy construction or assignment, that variable is either not used again at all, or else it is
used only as the target of an assignment.
In C++11, there is an std library function called std::move that comes to our rescue. It is a
function that turns its argument into an rvalue without doing anything else. Therefore, in
C++11, the std library function swap looks like this:

template<class T>
void swap(T& a, T& b)
{
T tmp(std::move(a));
a = std::move(b);
b = std::move(tmp);
}
X a, b;
swap(a, b);


Now all three lines in swap use move semantics. Note that for those types that do not
implement move semantics (that is, do not overload their copy constructor and assignment
operator with an rvalue reference version), the new swap behaves just like the old one.
std::move is a very simple function. Unfortunately, though, I cannot show you the
implementation yet. We'll come back to it later.
Using std::move wherever we can, as shown in the swap function above, gives us the
following important benefits:
· For those types that implement move semantics, many standard algorithms and
operations will use move semantics and thus experience a potentially significant
performance gain. An important example is inplace sorting: inplace sorting
algorithms do hardly anything else but swap elements, and this swapping will now
take advantage of move semantics for all types that provide it.
· The STL often requires copyability of certain types, e.g., types that can be used as
container elements. Upon close inspection, it turns out that in many cases,
moveability is enough. Therefore, we can now use types that are moveable but not
copyable (unique_pointer comes to mind) in many places where previously, they
were not allowed. For example, these types can now be used as STL container
elements.
Now that we know about std::move, we are in a position to see why the implementation of
the rvalue reference overload of the copy assignment operator that I showed earlier is still
a bit problematic. Consider a simple assignment between variables, like this:

a = b;

What do you expect to happen here? You expect the object held by a to be replaced by a
copy of b, and in the course of this replacement, you expect the object formerly held by a
to be destructed. Now consider the line

a = std::move(b);

If move semantics are implemented as a simple swap, then the effect of this is that the
objects held by a and b are being exchanged between a and b. Nothing is being destructed
yet. The object formerly held by “a” will of course be destructed eventually, namely, when
“b” goes out of scope. Unless, of course, b becomes the target of a move, in which case
the object formerly held by “a” gets passed on again. Therefore, as far as the implementer
of the copy assignment operator is concerned, it is not known when the object formerly
held by a will be destructed.
So in a sense, we have drifted into the netherworld of non-deterministic destruction
here: a variable has been assigned to, but the object formerly held by that variable is still
out there somewhere. That's fine as long as the destruction of that object does not have
any side effects that are visible to the outside world. But sometimes destructors do have
such side effects. An example would be the release of a lock inside a destructor.
Therefore, any part of an object's destruction that has side effects should be performed
explicitly in the rvalue reference overload of the copy assignment operator:

X& X::operator=(X&& rhs)
{
// Perform a cleanup that takes care of at least those parts of the
// destructor that have side effects. Be sure to leave the object
// in a destructible and assignable state.
// Move semantics: exchange content between this and rhs
return *this;
}


Is an Rvalue Reference an Rvalue?
As before, let X be a class for which we have overloaded the copy constructor and copy
assignment operator to implement move semantics. Now consider:

void foo(X&& x)
{
X anotherX = x;
// ...
}


The interesting question is: which overload of X's copy constructor gets called in the body
of foo? Here, x is a variable that is declared as an rvalue reference, that is, a reference
which preferably and typically (although not necessarily!) refers to an rvalue. Therefore, it
is quite plausible to expect that x itself should also bind like an rvalue, that is,
X(X&& rhs);
should be called. In other words, one might expect that anything that is declared as an
rvalue reference is itself an rvalue. The designers of rvalue references have chosen a
solution that is a bit more subtle than that:
Things that are declared as rvalue reference can be lvalues or rvalues. The distinguishing
criterion is: if it has a name, then it is an lvalue. Otherwise, it is an rvalue.
In the example above, the thing that is declared as an rvalue reference has a name, and
therefore, it is an lvalue:

void foo(X&& x)
{
X anotherX = x; // calls X(X const & rhs)
}


Here is an example of something that is declared as an rvalue reference and does not have
a name, and is therefore an rvalue:
X&& goo();
X x = goo(); // calls X(X&& rhs)
because the thing on
// the right hand side has no name
And here's the rationale behind the design: Allowing move sematics to be applied tacitly
to something that has a name, as in
X anotherX = x;
// x is still in scope!

would be dangerously confusing and error-prone because the thing from which we just
moved, that is, the thing that we just pilfered, is still accessible on subsequent lines of
code. But the whole point of move semantics was to apply it only where it "doesn't
matter," in the sense that the thing from which we move dies and goes away right after the
moving. Hence the rule, "If it has a name, then it's an lvalue."
So then what about the other part, "If it does not have a name, then it's an rvalue?"
Looking at the goo example above, it is technically possible, though not very likely, that
the expression goo() in the second line of the example refers to something that is still
accessible after it has been moved from. But recall from the previous section: sometimes
that's what we want! We want to be able to force move semantics on lvalues at our
discretion, and it is precisely the rule, "If it does not have a name, then it's an rvalue"
that allows us to achieve that in a controlled manner. That's how the function std::move
works. Although it is still too early to show you the exact implementation, we just got a
step closer to understanding std::move. It passes its argument right through by
reference, doing nothing with it at all, and its result type is rvalue reference. So the
expression
std::move(x)
is declared as an rvalue reference and does not have a name. Hence, it is an rvalue. Thus,
std::move "turns its argument into an rvalue even if it isn't," and it achieves that by "hiding
the name."
Here is an example that shows how important it is to be aware of the if-it-has-a-name
rule. Suppose you have written a class Base, and you have implemented move semantics
by overloading Base's copy constructor and assignment operator:

Base(Base const & rhs); // non-move semantics
Base(Base&& rhs); // move semantics


Now you write a class Derived that is derived from Base. In order to assure that move
semantics is applied to the Base part of your Derived objects, you must overload Derived's
copy constructor and assignment operator as well. Let's look at the copy constructor. The
copy assignment operator is handled analogously. The version for lvalues is
straightforward:

Derived(Derived const & rhs)
: Base(rhs)
{
// Derived-specific stuff
}


The version for rvalues has a big fat subtlety. Here's what someone who is not aware of
the if-it-has-a-name rule might have done:

Derived(Derived&& rhs)
: Base(rhs) // wrong: rhs is an lvalue
{
// Derived-specific stuff
}


If we were to code it like that, the non-moving version of Base's copy constructor would
be called, because rhs, having a name, is an lvalue. What we want to be called is Base's
moving copy constructor, and the way to get that is to write

Derived(Derived&& rhs)
: Base(std::move(rhs)) // good, calls Base(Base&& rhs)
{
// Derived-specific stuff
}


Move Semantics and Compiler Optimizations
Consider the following function definition:

X foo()
{
X x;
// perhaps do something to x
return x;
}


Now suppose that as before, X is a class for which we have overloaded the copy
constructor and copy assignment operator to implement move semantics. If you take the
function definition above at face value, you may be tempted to say, wait a minute, there is
a value copy happening here from x to the location of foo's return value. Let me make sure
we're using move semantics instead:

X foo()
{
X x;
// perhaps do something to x
return std::move(x); // making it worse!
}


Unfortunately, that would make things worse rather than better. Any modern compiler
will apply return value optimization to the original function definition. In other words,
rather than constructing an X locally and then copying it out, the compiler would
construct the X object directly at the location of foo's return value. Rather obviously,
that's even better than move semantics.
So as you can see, in order to really use rvalue references and move semantics in an
optimal way, you need to fully understand and take into account today's compilers'
"special effects" such as return value optimization and copy elision. Dave Abrahams has
written an excellent series of articles on this subject on his blog. The details get pretty
subtle, but hey, we chose C++ as our language of choice for a reason, right? We made our
beds, so now let's lie in them.

Perfect Forwarding: The Problem

The other problem besides move semantics that rvalue references were designed to solve
is the perfect forwarding problem. Consider the following simple factory function:

template<typename T, typename Arg>
shared_ptr<T> factory(Arg arg)
{
return shared_ptr<T>(new T(arg));
}


Obviously, the intent here is to forward the argument arg from the factory function to T's
constructor. Ideally, as far as arg is concerned, everything should behave just as if the
factory function weren't there and the constructor were called directly in the client code:
perfect forwarding. The code above fails miserably at that: it introduces an extra call by
value, which is particularly bad if the constructor takes its argument by reference.
The most common solution, chosen e.g. by boost::bind, is to let the outer function take
the argument by reference:

template<typename T, typename Arg>
shared_ptr<T> factory(Arg& arg)
{
return shared_ptr<T>(new T(arg));
}


That's better, but not perfect. The problem is that now, the factory function cannot be
called on rvalues:

factory<X>(hoo()); // error if hoo returns by value
factory<X>(41); // error


This can be fixed by providing an overload which takes its argument by const reference:

template<typename T, typename Arg>
shared_ptr<T> factory(Arg const & arg)
{
return shared_ptr<T>(new T(arg));
}


There are two problems with this approach. Firstly, if factory had not one, but several
arguments, you would have to provide overloads for all combinations of non-const and
const reference for the various arguments. Thus, the solution scales extremely poorly to
functions with several arguments.
Secondly, this kind of forwarding is less than perfect because it blocks out move
semantics: the argument of the copy constructor of T in the body of factory is an lvalue.
Therefore, move semantics can never happen even if it would without the wrapping
function.
It turns out that rvalue references can be used to solve both these problems. They make it
possible to achieve truly perfect forwarding without the use of overloads. In order to
understand how, we need to look at two more rules for rvalue references.

Perfect Forwarding: The Solution
The first of the remaining two rules for rvalue references affects old-style lvalue
references as well. Recall that in pre-11 C++, it was not allowed to take a reference to a
reference: something like A& & would cause a compile error. C++11, by contrast,
introduces the following reference collapsing rules:
· A& & becomes A&
· A& && becomes A&
· A&& & becomes A&
· A&& && becomes A&&
Secondly, there is a special template argument deduction rule for function templates that
take an argument by rvalue reference to a template argument:

template<typename T>
void foo(T&&);


Here, the following apply:
1. When foo is called on an lvalue of type A, then T resolves to A& and hence, by the
reference collapsing rules above, the argument type effectively becomes A&.
2. When foo is called on an rvalue of type A, then T resolves to A, and hence the
argument type becomes A&&.
Given these rules, we can now use rvalue references to solve the perfect forwarding
problem as set forth in the previous section. Here's what the solution looks like:

template<typename T, typename Arg>
shared_ptr<T> factory(Arg&& arg)
{
return shared_ptr<T>(new T(std::forward<Arg>(arg)));
}


where std::forward is defined as follows:

template<class S>
S&& forward(typename remove_reference<S>::type& a) noexcept
{
return static_cast<S&&>(a);
}


(Don't pay attention to the noexcept keyword for now. It lets the compiler know, for
certain optimization purposes, that this function will never throw an exception. We'll come
back to it in Section 9.) To see how the code above achieves perfect forwarding, we will
discuss separately what happens when our factory function gets called on lvalues and
rvalues. Let A and X be types. Suppose first that factory<A> is called on an lvalue of type

X:
X x;
factory<A>(x);


Then, by the special template deduction rule stated above, factory's template argument
Arg resolves to X&. Therefore, the compiler will create the following instantiations of
factory and std::forward:

shared_ptr<A> factory(X& && arg)
{
return shared_ptr<A>(new A(std::forward<X&>(arg)));
}
X& && forward(remove_reference<X&>::type& a) noexcept
{
return static_cast<X& &&>(a);
}


After evaluating the remove_reference and applying the reference collapsing rules, this
becomes:

shared_ptr<A> factory(X& arg)
{
return shared_ptr<A>(new A(std::forward<X&>(arg)));
}
X& std::forward(X& a)
{
return static_cast<X&>(a);
}


This is certainly perfect forwarding for lvalues: the argument arg of the factory function
gets passed on to A's constructor through two levels of indirection, both by old-fashioned
lvalue reference.
Next, suppose that factory<A> is called on an rvalue of type X:

X foo();
factory<A>(foo());


Then, again by the special template deduction rule stated above, factory's template
argument Arg resolves to X. Therefore, the compiler will now create the following
function template instantiations:

shared_ptr<A> factory(X&& arg)
{
return shared_ptr<A>(new A(std::forward<X>(arg)));
}
X&& forward(X& a) noexcept
{
return static_cast<X&&>(a);
}


This is indeed perfect forwarding for rvalues: the argument of the factory function gets
passed on to A's constructor through two levels of indirection, both by reference.
Moreover, A's constructor sees as its argument an expression that is declared as an rvalue
reference and does not have a name. By the no-name rule, such a thing is an rvalue.
Therefore, A's constructor gets called on an rvalue. This means that the forwarding
preserves any move semantics that would have taken place if the factory wrapper were not
present.
It is perhaps worth noting that the preservation of move semantics is in fact the only
purpose of std::forward in this context. Without the use of std::forward, everything would
work quite nicely, except that A's constructor would always see as its argument
something that has a name, and such a thing is an lvalue. Another way of putting this is
to say that std::forward's purpose is to forward the information whether at the call site,
the wrapper saw an lvalue or an rvalue.
If you want to dig a little deeper for extra credit, ask yourself this question: why is the
remove_reference in the definition of std::forward needed? The answer is, it is not really
needed at all. If you use just S& instead of remove_reference<S>::type& in the defintion
of std::forward, you can repeat the case distinction above to convince yourself that
perfect forwarding still works just fine. However, it works fine only as long as we
explicitly specify Arg as the template argument of std::forward. The purpose of the
remove_reference in the definition of std::forward is to force us to do so.
Rejoice. We're almost done. It only remains to look at the implementation of std::move.
Remember, the purpose of std::move is to pass its argument right through by reference
and make it bind like an rvalue. Here's the implementation:

template<class T>
typename remove_reference<T>::type&&
std::move(T&& a) noexcept
{
typedef typename remove_reference<T>::type&& RvalRef;
return static_cast<RvalRef>(a);
}
Suppose that we call std::move on an lvalue of type X:
X x;
std::move(x);


By the new special template deduction rule, the template argument T will resolve to X&.
Therefore, what the compiler ends up instantiating is

typename remove_reference<X&>::type&&
std::move(X& && a) noexcept
{
typedef typename remove_reference<X&>::type&& RvalRef;
return static_cast<RvalRef>(a);
}


After evaluating the remove_reference and applying the new reference collapsing rules,
this becomes

X&& std::move(X& a) noexcept
{
return static_cast<X&&>(a);
}


That does the job: our lvalue x will bind to the lvalue reference that is the argument type,
and the function passes it right through, turning it into an unnamed rvalue reference.
I leave it to you to convince yourself that std::move actually works fine when called on an
rvalue. But then you may want to skip that: why would anybody want to call std::move
on an rvalue, when its only purpose is to turn things into rvalues? Also, you have
probably noticed by now that instead of
std::move(x);
you could just as well write
static_cast<X&&>(x);
However, std::move is strongly preferred because it is more expressive.

Rvalue References And Exceptions
Normally, when you develop software in C++, it is your choice whether you want to pay
attention to exception safety, or to use exceptions at all in your code. Rvalue references
are a bit different in this regard. When you overload the copy constructor and the copy
assignment operator of a class for the sake of move semantics, it is very much
recommended that you do the following:
1. Strive to write your overloads in such a way that they cannot throw exceptions. That
is often trivial, because move semantics typically do no more than exchange
pointers and resource handles between two objects.
2. If you succeeded in not throwing exceptions from your overloads, then make sure to
advertise that fact using the new noexcept keyword.
If you don't do both of these things, then there is at least one very common situation
where your move semantics will not be applied despite the fact that you would very
much expect it: when an std::vector gets resized, you certainly want move semantics to
happen when the existing elements of your vector are being relocated to the new
memory block. But that won't happen unless both of 1. and 2. above are satisfied.
The reasons for this behavior are rather complex. For the full story, see Dave Abrahams'
blog entry on the subject. Note that the blog entry was written before the solution using
noexcept was introduced. The blog entry describes the problem; to understand how
noexcept is used to solve the problem, follow the link under "update #2" at the top of the
blog entry.

The Case of the Implicit Move
At one point during the (often complex and controversial) discussion of rvalue references,
the Standard Committee decided that move constructors and move assignment operators,
that is, rvalue reference overloads for copy constructors and copy assignment operators,
should be generated by the compiler when not provided by the user. This seems like a
natural and plausible thing to request, considering that the compiler has always done the
exact same thing for ordinary copy constructors and copy assignment operators. In August
of 2010, Scott Meyers posted a message on comp.lang.c++ in which he explained how
compiler-generated move constructors can break existing code in a rather serious way.
Dave Abrahams has summarized the problem in this blog entry.
The committee then decided that this was indeed cause for alarm, and it restricted the
automatic generation of move constructors and move assignment operators in such a
way that it is much less likely, though not impossible, for existing code to break. The
committee's decision is summarized in this blog post by Herb Sutter.
The issue of implicitly moving remained controversial all the way up to the finalization of
the Standard (see e.g. this blog post by Dave Abrahams and the ensuing discussion). In an
ironic twist of fate, the only reason why the committee considered implicit move in the
first place was as an attempt to resolve the issue with rvalue references and exceptions
as mentioned in Section 9. This problem was subsequently solved in a more satisfactory
way via the new noexcept keyword. Had the noexcept solution been found just a few
months earlier, implicit move may have never seen the light of day. Oh well, so it goes.
Ok, that's it, the whole story on rvalue references. As you can see, the benefits are
considerable. The details are gory. As a C++ professional, you will have to understand
these details. Otherwise, you have given up on fully understanding the central tool of
your trade. You can take solace, though, in the thought that in your day-to-day
programming, you will only have to remember three things about rvalue references:
1. By overloading a function like this:

void foo(X& x); // lvalue reference overload
void foo(X&& x); // rvalue reference overload


you can branch at compile time on the condition "is foo being called on an lvalue or
an rvalue?" The primary (and for all practical purposes, the only) application of that
is to overload the copy constructor and copy assignment operator of a class for the
sake of implementing move semantics. If and when you do that, make sure to pay
attention to exception handling, and use the new noexcept keyword as much as you
can.
2. std::move turns its argument into an rvalue.
3. std::forward allows you to achieve perfect forwarding if you use it exactly as shown
in the factory function
ENJOY!


How to: Write a Move Constructor
// MemoryBlock.h
#pragma once
#include <iostream>
#include <algorithm>
class MemoryBlock
{
public:
// Simple constructor that initializes the resource.
explicit MemoryBlock(size_t length)
: _length(length)
, _data(new int[length])
{
std::cout << "In MemoryBlock(size_t). length = "
<< _length << "." << std::endl;
}
// Destructor.
~MemoryBlock()
{
std::cout << "In ~MemoryBlock(). length = "
<< _length << ".";
if (_data != NULL)
{
std::cout << " Deleting resource.";
// Delete the resource.
delete[] _data;
}
std::cout << std::endl;
}
// Copy constructor.
MemoryBlock(const MemoryBlock& other)
: _length(other._length)
, _data(new int[other._length])
{
std::cout << "In MemoryBlock(const MemoryBlock&). length = "
<< other._length << ". Copying resource." << std::endl;
std::copy(other._data, other._data + _length, _data);
}
// Copy assignment operator.
MemoryBlock& operator=(const MemoryBlock& other)
{
std::cout << "In operator=(const MemoryBlock&). length = "
<< other._length << ". Copying resource." << std::endl;
if (this != &other)
{
// Free the existing resource.
delete[] _data;
_length = other._length;
_data = new int[_length];
std::copy(other._data, other._data + _length, _data);
}
return *this;
}
// Retrieves the length of the data resource.
size_t Length() const
{
return _length;
}
private:
size_t _length; // The length of the resource.
int* _data; // The resource.
};


The following procedures describe how to write a move constructor and a move
assignment operator for the example C++ class.
To create a move constructor for a C++ class
1. Define an empty constructor method that takes an rvalue reference to the
class type as its parameter, as demonstrated in the following example:
C++

MemoryBlock(MemoryBlock&& other)
: _data(NULL)
, _length(0)
{
}


2. In the move constructor, assign the class data members from the source
object to the object that is being constructed:
C++

_data = other._data;
_length = other._length;


3. Assign the data members of the source object to default values. This
prevents the destructor from freeing resources (such as memory) multiple
times:

other._data = NULL;
other._length = 0;


To create a move assignment operator for a C++ class
1. Define an empty assignment operator that takes an rvalue reference to the
class type as its parameter and returns a reference to the class type, as
demonstrated in the following example:

MemoryBlock& operator=(MemoryBlock&& other)
{
}


2. In the move assignment operator, add a conditional statement that
performs no operation if you try to assign the object to itself.

if (this != &other)
{
}


3. In the conditional statement, free any resources (such as memory) from the
object that is being assigned to.
The following example frees the _data member from the object that is
being assigned to:

// Free the existing resource.
delete[] _data;


Follow steps 2 and 3 in the first procedure to transfer the data members
from the source object to the object that is being constructed:

// Copy the data pointer and its length from the
// source object.
_data = other._data;
_length = other._length;
// Release the data pointer from the source object so that
// the destructor does not free the memory multiple times.
other._data = NULL;
other._length = 0;


4. Return a reference to the current object, as shown in the following
example:

return *this;

Example
The following example shows the complete move constructor and move
assignment operator for the MemoryBlock class:

// Move constructor.
MemoryBlock(MemoryBlock&& other)
: _data(NULL)
, _length(0)
{
std::cout << "In MemoryBlock(MemoryBlock&&). length = "
<< other._length << ". Moving resource." << std::endl;
// Copy the data pointer and its length from the
// source object.
_data = other._data;
_length = other._length;
// Release the data pointer from the source object so that
// the destructor does not free the memory multiple times.
other._data = NULL;
other._length = 0;
}
// Move assignment operator.
MemoryBlock& operator=(MemoryBlock&& other)
{
std::cout << "In operator=(MemoryBlock&&). length = "
<< other._length << "." << std::endl;
if (this != &other)
{
// Free the existing resource.
delete[] _data;
// Copy the data pointer and its length from the
// source object.
_data = other._data;
_length = other._length;
// Release the data pointer from the source object so that
// the destructor does not free the memory multiple times.
other._data = NULL;
other._length = 0;
}
return *this;
}


Monday, April 8, 2013

C++ 11 : Range-based for loop

C++ 11 has a new feature included in it i.e.; Range-based For loop. You might be wondering about what is range-based for loop. So, it is similar to the standard c++ for loop, or you can also say that it is the brother of foreach, which executes the statement repeatedly and sequentially for each element in the expression.

Syntax:-

for(for-range-declaration : expression)
     statement

Let see an example on this:-

#include <iostream>

using namespace std;

int main()
{
     int x[10] = {1,2,3,4,5,6,7,8,9,10};
     for(auto &i : x) // Access by using reference of the variable
     {
            cout<<i<<endl;
     }
      return 0;
}

It will iterate through all over the array and show the output. You can use it in all C++ STL classes.
For example:-

int main()
{
     vector<int> vec;
     vec.push_back(10);
     vec.push_back(20);
     vec.push_back(30);

      for(auto i : vec) //  Access by using copy of the variable
            cout<<i<<endl;
      return 0;
}

The above code print all the contents in the vector vec.
 A range based for loop terminates when one of these statement executes: a break, a goto, or a  return. A continue statement in the range based for loop terminates only the current iteration.

C++11 : Auto, Lambda Expression and decltype


Auto keyword

int x = 3;
auto y = x;

The compiler will deduce that y is an int. This, of course, isn't a shining example of where auto is really useful. 
Auto really comes into its own when working with templates and especially the STL.
Now take another example, you want to iterate over a vector. So for that, you need an iterator:
map<string, string>::iterator itr = address_book.begin(); 

This above declaration is somewhat looking weird. Simply you can write the above statement as:  
auto itr = address_book.begin();

Lambda Functions  


C++11 provides support for anonymous functions, called lambda functions.  
Syntax:-
[capture](parameters)->return-type{body}

If there are no parameters the empty parentheses can be omitted.
[capture]->return-type{body}

The return type can often be omitted, if the body consists only of one return statement or the return type is void.
[capture](parameters){body} 

[]        //no variables defined. Attempting to use any external variables in the lambda is an error.
[x, &y]   //x is captured by value, y is captured by reference 
[&]       //any external variable is implicitly captured by reference if used 
[=]       //any external variable is implicitly captured by value if used
[&, x]    //x is explicitly captured by value. Other variables will be captured by reference.
[=, &z]   //z is explicitly captured by reference. Other variables will be captured by value.
[this]  //Capture the this pointer of the enclosing class

For example:-
Example 1:-
int main()
{
    int x = 5;
    int y;
    auto func = [=,&y](){y=x;};//x is read only(=), y is reference(&)
    func();
   return 0;
}

Example 2:-
class Foo
{
public:
    Foo () : _x( 3 ) {}
    void func ()
    {
        // a very silly, but illustrative way of printing out the value of _x
        [this] () { cout << _x; } ();
    }

private:
        int _x;
};

Decltype

Now, the question arising in your mind is that, if we didn't explicitly provide the return type then, how the compiler knows about the return type.
So, there is an another C++11 feature by which the compile extract the return type information,
i.e; decltype() 

Auto lets you declare a variable with a particular type; decltype lets you extract the type 
from a variable (or any other expression). 
For example:-

int x = 3;
decltype(x) y = x; //decltype(x) will extract the return type of x

The above example is the simple one.
Now, Let we talk in terms of lambda, means where it is used. So check this example:-
[](int x, int y) { return x + y; } // implicit return type from 'return' statement

The return type of this unnamed function is decltype(x+y). The return type can be omitted if the lambda function is of the form return expression(i.e.;[](int x, int y)->int), or if all locations that return a value return the same type when the return expression is passed through decltype.