C++14 decltype auto : uses

A new type specifier known as C++14 decltype auto (or decltype(auto) ) has been added. The sole purpose of this type specifier is to make the auto deduce the type of the initializer like the decltype type specifier. In other words, it enforces decltype rule in auto when deducing the type.

Link : C++ decltype

Like the auto, decltype(auto) type specifier will deduce the type from the initializer assign to the object. You can use it in your program like the auto type specifier.

**NOTE:: decltype( auto ) is an auto, but it uses delctype() rule to determine the type of the variable or object.
 
Link : C++ auto keyword

int i=89 ;
decltype(auto) da=i ; //da is int type

auto daa=i ; //daa is int type

cout<< da ;

Similarity between decltype() and decltype(auto)

One thing you must clearly understand is although decltype(auto) is an auto type specifier, it will deduce the type like the decltype type specifier. So all the type deduction rule of decltype also applies to decltype(auto).
Consider the code below.

int i=89 , &iref=i ;

auto au=((i)) ; //au is int type


decltype((i)) dt=iref ; //dt is int& type

decltype(auto) dau=((i)) ; //dau is int& type

You can clearly see the similarity between decltype() and decltype(auto) in the code example given above. Both the type specifier- decltype((i)) and decltype(auto), deduced the type of the initializer as a reference to int type whereas auto deduce the type as an int type.

Another example of the similarity between decltype and decltype(auto) is when using them to specify the return type of a function. Consider the functions below where auto, decltype and decltype(auto) is used to specify the return type of the functions.

int i;

auto funcAuto(int i)
{
return (++i) ;
}

decltype(auto) funcDecltypeAuto(int i)
{
return (++i) ;
}

decltype((i)) funcDecltype(int i)
{
return (++i) ;
}

int main( )
{
funcAuto(45)= 78; //error!

funcDecltypeAuto(34) =78 ; //work fine

funcDecltype(23)=67 ; //work fine

return 0;
}

Since the return type of funcDecltype() and funcDecltypeAuto() is a reference to int type, the returned object can be used as lvalue and so assigning a value to it is allowed. But in case of auto, the type return is an int type literal value so it cannot be used as a lvalue or further assignment of the value to the return object is prohibited.



Some more examples on auto, decltype() and decltype(auto)

Here are some more example on how the type deduce by auto and decltype() and decltype(auto) differ.

int val=89 , &ref=val , &refnew=val ;

/**
deducing a reference initializer
***/
auto a1=ref ; // a1 is int type

decltype(ref) dec1= 89 ; //error because dec1 is 'int&' type
decltype(ref) dec2=refnew ; //work fine 
decltype(auto) decau= ref ; //decau is 'int&' type

/***
deducing an object with '&'
****/
auto a2 = &val ; //s2 is int* type

decltype(&val) dec3 = &ref ; //dec3 is 'int*' type
decltype(auto) decau1 = &val ; //decau1 is 'int*' type

/***
deducing a const pointer object
****/
const int cval = 34 , *ip=&val ;

auto a3 = ip ; //a3 is 'const int*' type

decltype(ip) dec4 = ip ; //dec4 is 'const int*' type
decltype(auto) decau2 = ip ; //decau2 is 'const int*' type

Conclusion

The use of decltype(auto) is to deduce the return type of a function. And mainly so when you want the type deduced to be of reference type when a literal is the return value. We can use dectype() in such function but it would mean declaring an extra variable to pass as an argument when decltype() is call. But,with decltype(auto) the extra declaration of the variable is omitted.