Universal reference and Perfect forwarding
==========================================
Universal refrence is used in case of type deduction.
class X;
void f(X&& param);      
X&& var1 = X();         
auto&& var2 = var1;     
template <typename T>
void f(std::vector<T>&& param); 
template <typename T>
void f(T&& param);       
template <typename T>
void f(const T&& param); 
X var;
f(var);                 
f(std::move(var));      
std::vector<int> v;
f(v);           
template <class T, class Allocator = allocator<T>>
class vector
{
public:
  void push_back(T&& x);  
  
};
template <class T, class Allocator = allocator<T>>
class vector
{
public:
  template <class... Args>
  void emplace_back(Args&&... args);    
  
};
Perfect forwarding
==================
template<typename T, typename Arg>
shared_ptr<T> factory(Arg arg)
{
  return shared_ptr<T>(new T(arg));
}
Unfortunately, this will call T(arg) by value.
A half-good solution is passing arg by reference:
template<typename T, typename Arg>
shared_ptr<T> factory(Arg& arg)
{
  return shared_ptr<T>(new T(arg));
}
But this does not work for rvalue parameters:
factory<X>(f());        
factory<X>(42);         
So we can add an overloaded factory function:
template<typename T, typename Arg>
shared_ptr<T> factory(const Arg& arg)
{
  return shared_ptr<T>(new T(arg));
}
Here is the issue:
-- If factory has many arguments, we have to provide all combinations
   of const and non-const references.
-- arg parameter inside factory() is an lvalue --> no move semantics
Reference collapsing
====================
In pre-C++11 no way to set a reference to a reference: A& & is a compile error
In C++11 we have "reference collapsing" rule:
  A& &   --> A&
  A& &&  --> A&
  A&& &  --> A&
  A&& && --> A&&
template <typename T>
void f(T&&);            
- If f() called on "lvalue of A"  T --> A&     argument type --> A&
- If f() called on "rvalue of A"  T --> A      argument type --> A
template<typename T, typename Arg>
shared_ptr<T> factory(Arg&& arg)
{
  return shared_ptr<T>(new T(std::forward<Arg>(arg)));
}
template<class S>
S&& forward(typename remove_reference<S>::type& a) noexcept
{
  return static_cast<S&&>(a);
}
Examples:
X x;
factory<A>(x);         Arg --> X&
X& && forward(remove_reference<X&>::type& a) noexcept
{
  return static_cast<X& &&>(a);
}
shared_ptr<A> factory(X& && arg)
{
  return shared_ptr<A>(new A(std::forward<X&>(arg)));
}
which 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);
}
X foo();
factory<A>(foo());      Arg --> X
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);
}
std::forward --> keeps move semantic
std::remove_reference<S>::type&  == S&
template <typename T>           
typename remove_reference<T>::type&&
std::move(T&& a) noexcept
{
  typedef typename remove_reference<T>::type&& RvalRef;
  return static_cast<RvalRef>(a);
}
template <typename T>           
decltype(auto) std::move(T&& a)
{
  using ReturnType = remove_reference_t<T>&&;
  return static_cast<ReturnType>(a);
}
std::move(x)   <===>   static_cast<X&&>(x)