C++11 - Type Deduction

Template Type Deduction

Reference arguments are treated as non-references.
For Universal Reference Parameters, lvalue arguments are deduced as lvalue references.
For By Value Parameters, Const and Volatile arguments are treated as non-const and non-volatile.
Arrays and Functions names decay to pointers or references.

Scenario 1 -
For template<class T> void f(T& param);
For these variable declarations -
int x;
const int cx = x;
const int & rx = x;

These calls to f will deduce type for T as -
f(x); //T is int, param is int&
f(cx); //T is const int, param is const int&
f(rx); //T is const int, param is const int&

Scenario 2 -
For template<class T> void f(const T& param);
For these variable declarations -
int x;
const int cx = x;
const int & rx = x;

These calls to f will deduce type for T as -
f(x); //T is int, param is const int&
f(cx); //T is int, param is const int&
f(rx); //T is int, param is const int&

Scenario 3 -
For template<class T> void f(T * param);
For these variable declarations -
int x;
const int * px = &x;

These calls to f will deduce type for T as -
f(&x); //T is int, param is int*
f(px); //T is const int, param is const int*

Scenario 4 -
For template<class T> void f(T&& param);
For these variable declarations -
int x;
const int cx = x;
const int & rx = x;

These calls to f will deduce type for T as -
f(x); //T is int&, param is int&
f(cx); //T is const int&, param is const int&
f(rx); //T is const int&, param is const int&
f(99); //T is int, param is int&&

Scenario 5 -
For template<class T> void f(T param);
For these variable declarations -
int x;
const int cx = x;
const int & rx = x;

These calls to f will deduce type for T as -
f(x); //T is int, param is int
f(cx); //T is int, param is int
f(rx); //T is int, param is int

const char * const p = "const pointer to const string";
const to the right of asterix ensures p can't be made to point to a different location and the const to the left of asterix ensures that the string p points to can't be changed.
f(p);
p is passed by value i.e. const to the right of the asterix is lost. param is deduced to be const char * i.e. p points to a constant string, p itself can be made to point to something else, however since it's passed by value the value of p outside the function f remains unchanged.

const char array[] = "abcd";
const char * ptr = array;
f(array); //T is const char *, param is const char *
If the template were defined as template<class T> void g(T & param);
g(array); //T is const char[5], param is const char(&)[5]

Scenario 6 -
For template<class T> void f(T param);
template<class T&> void g(T& param);
For this function declaration
void h(int);

These calls to f and g will deduce type for T as -
f(h); //T is void (*)(int), param is ptr to function
g(h); //T is void (&)(int), param is ref to function

auto Type Deduction

Deducing type for auto is the same as template type deduction. However when the variable is initialized using braces the deduced type is std::initializer_list. For e.g. -
int x1 = 1;
auto x2 = 1; //both x1 and x2 are deduced as int's
int y1(1);
auto y2(1); //both y1 and y2 are deduced as int's
int z1 = {1}; //z1 is int
auto z2 = {1}; //z2 is type std::initializer_list<int>
int z3{ 1 }; //z3 is int
auto z4{ 1 }; //z4 is type std::initalizer_list<int>

However template type deduction will not deduce braced initializer as std::initializer_list<T> -
template<class T> void f(T param);
f({1, 2, 3}); //error will not deduce T to std::initializer_list
If the template were modified to 
template<class T> void f(std::initializer_list<T> param);
then the call to f would work.

auto in a function return type works as template type deduction and will not deduce braced initializer as std::initializer_list -
auto f()
{
    return { 1, 2, 3 }; //error will not deduce return type as std::initializer_list<int>
}