When to use decltype(auto) versus auto?

Hi,

When and why is it necessary or convenient to use
decltype(auto)
on return types or type deduction versus plain
auto
?

Thanks,

Juan

P.S.: I have read so much about this that I am more confused!!
See http://www.cplusplus.com/forum/general/186478/#msg908872

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>

// returns prvalue: plain auto never deduces to a reference
template < typename T > auto foo( T& t ) { return t.value() ; }

// return lvalue: auto& always deduces to a reference
template < typename T > auto& bar( T& t ) { return t.value() ; }

// return prvalue if t.value() is an rvalue
// return lvalue if t.value is an lvalue
// decltype(auto) has decltype semantics (without having to repeat the expression).
template < typename T > decltype(auto) foobar( T& t ) { return t.value() ; }

int main()
{
   struct A { int i = 0 ; int& value() { return i ; } } a;
   struct B { int i = 0 ; int value() { return i ; } } b;

   foo(a) = 20 ; // *** error: expression evaluates to prvalue of type int
   foo(b) ; // fine: expression evaluates to prvalue of type int

   bar(a) = 20 ; // fine: expression evaluates to lvalue of type int
   bar(b) ; // *** error: auto& always deduces to a reference

   foobar(a) = 20 ; // fine: expression evaluates to lvalue of type int
   foobar(b) ; // fine: expression evaluates to prvalue of type int
}

http://coliru.stacked-crooked.com/a/908009faf15bd641
Ok... being this so, why would we want to use
auto
or
auto&
for a return value?
Use auto when we want to return a prvalue, but want the type to be deduced.
Use auto& or const auto& when we want to return an lvalue, but want the type to be deduced.

Use declspec(auto) when we want decltype semantics for the deduced return type.
(This is mainly useful when we write forwarding templates.)

If the return type does not use decltype(auto), the deduction follows the rules of template argument deduction.
...
If the return type is decltype(auto), the return type is as what would be obtained if the expression used in the return statement were wrapped in decltype.
http://en.cppreference.com/w/cpp/language/function
Is there ever a case where decltype(auto) fails in certain situations when auto or auto& would have gotten the job done correctly?
1
2
3
4
5
6
7
8
9
10
11
auto foo()
{
    int x = 0 ;
    return (x) ; // fine
}

decltype(auto) bar()
{
    int x = 0 ;
    return (x) ; // trouble
}
Topic archived. No new replies allowed.