rvalue
lvalue reference and ravlue reference
#include <iostream>
#include <string>

//lvalue reference
void display(std::string &str)
{
	std::cout<<"Pass lvalue"<<std::endl;
	str = str+" --- lvalue";
	std::cout<<str<<std::endl;
}

//rvalue reference
void display(std::string && str)
{
	std::cout<<"Pass rvalue"<<std::endl;
	str = str + " --- rvalue";
	std::cout<<str<<std::endl;
}

std::string getStr()
{
	return "Get String ...";
}

int main(int argc, char *argv[])
{
	std::string str = "Hello";

	//call lvalue reference
	display(str);
	std::cout<<"Str: "<<str<<std::endl;

	//call rvalue reference
	display(std::move(str));
	std::cout<<"Str: "<<str<<std::endl;

	//call rvalue reference
	display(getStr());

	//call rvalue reference
	display("Hello World!");

	return 0;
}
			
Is rvalue immutable in C++?
#ifndef V_H
#define V_H
class V
{
	private:
		int size;
		int *array;
	public:
		//constructor
		V(int s):size(s)
		{
			std::cout<<"Constructor ..."<<std::endl;
			array = new int[size];
			for(int i = 0; i < size; i++)
				array[i] = 10*i;
			std::cout<<"----End Constructor ..."<<std::endl;
		}

		//copy constructor
		V(const V &right):size(right.size), array(size?new int [size]:nullptr)
		{
			std::cout<<"Copy Constructor ..."<<std::endl;
			std::copy(right.array, right.array+size, array);
			std::cout<<"----End Copy Constructor ..."<<std::endl;
		}

		//move constructor
		V(V && right):size(0), array(nullptr)
		{
			std::cout<<"Move Constructor ..."<<std::endl;
			size = right.size;
			array = right.array;
			right.size = 0;
			right.array =  nullptr;
			std::cout<<"----End Move Constructor ..."<<std::endl;
		}

		int *getAddress() const {return array;}
		int getSize() const {return size;}

		void display() const
		{
			for(int i = 0; i < size; i++)
				std::cout<<array[i]<<" ";
			std::cout<<std::endl;
		}

		V & time(int n)
		{
			for(int i = 0; i < size; i++)
				array[i] *= n;
			return *this;
		}

		//copy assignment
		const V& operator=(const V &right)
		{
			std::cout<<"Copy Assignment ..."<<size<<std::endl;
			if(this != &right)
			{
				V temp(right);
				std::swap(size, temp.size);
				std::swap(array, temp.array);
				std::cout<<"----End Assignment ..."<<std::endl;
			}

			return *this;
		}

		//move assignment
		V & operator=(V&& right)
		{
			std::cout<<"Move Assignment ..."<<std::endl;
			if(this != &right)
			{
				delete [] array;
				array = 0;
				size = 0;

				size = right.size;
				array = right.array;

				right.size = 0;
				right.array = nullptr;
			}
			std::cout<<"----End Move Assignment ..."<<std::endl;

			return *this;
		}

		~V()
		{
			std::cout<<"Destructor ..."<<size<<std::endl;
			delete array;
			array = 0;
			size = 0;
		}
};
#endif
			
#include <iostream>
#include "V.h"

//return an object
V getObject()
{
	std::cout<<"Inside function ..."<<std::endl;
	//call constructor
	V v(10);

	std::cout<<"Return from function ..."<<std::endl;
	return v;
}

//pass by lvalue reference
void byRef(V &v) 
{
	std::cout<<"-------Pass by lvalue reference-------"<<std::endl;
}

//pass by constant lvalue reference
void byRef(const V &v) 
{
	std::cout<<"-------Pass by constant lvalue reference-------"<<std::endl;
}

//pass by rvalue reference
void byRef(V &&v) 
{
	std::cout<<"-------Pass by rvalue reference-------"<<std::endl;
	v.time(2);
	v.display();
}
void byRef(const V&& v) 
{
	std::cout<<"-------Pass by constant rvalue reference-------"<<std::endl;
}

int main(int argc, char *argv[])
{
	//V *ptr = &getObject();//compile error, rvalue
	V v(10);

	//pass by lvalue reference
	byRef(v);

	//pass by rvalue reference
	byRef(getObject());
	byRef(std::move(getObject()));
	byRef(std::move(v));

	//immutable and mutable
	//int x;
	//(x+7) = 7;//compile error
	V v2 = getObject().time(10);

	std::cout<<"Assign to itself ..."<<std::endl;
	v2 = v2.time(2);

	std::cout<<"Assign to another object ..."<<std::endl;
	v2 = v.time(2);//call copy assignment
	v.time(2);
	//v2 = std::move(v);//call move assignment
	v.display();
	v2.display();


	return 0;
}
			
Type Deduction
#include <iostream>

template <class T>
void f(T& param)
{
	//param++;
	std::cout<<param<<std::endl;
}

int main(int argc, char *argv[])
{
	int x = 22;
	f(x);//x is int&

	const int cx = x;
	f(cx);//cx is const int&

	const int& rx = x;
	f(rx);//rx is const int&

	int v = 22;
	auto&  v1 = v;//v1 is int&

	const int cv = v;
	auto& v2 = cv;//v2 is const int&

	const int& rx = v;
	auto& v3 = rx;//v3 is const int

	return 0;
}
			
#include <iostream>
#include <string>
#include <utility>

template <class T>
void display(T &p)
{
	std::cout<<"Pass lvalue: "<<p<<std::endl;
}

template <class T>
void display(T &&p)
{
	std::cout<<"Pass rvalue: "<<p<<std::endl;
}

int main(int argc, char *argv[])
{
	std::string str = "Hello World!";
	display(str);//lvalue
	display("Hello World!");//lvalue
	display(std::forward<std::string>("Hello World!"));//rvalue
	display(std::move(str));//rvalue

	return 0;
}
		
TRR
T&&T&
T&&&T&
T&&&T&
T&&&&T&&
#include <iostream>
#include <string>

template <class T>
void display(T &&p)//universal reference
{
	std::cout<<"Universal reference: "<<p<<std::endl;
}

int main(int argc, char *argv[])
{
	std::string str = "Hello World!";
	display(str);//lvalue
	display("Hello World!");//rvalue
	display(std::forward<std::string>("Hello World!"));//rvalue
	display(std::move(str));//rvalue

	return 0;
}