What is the difference between auto and decltype(auto) when returning from a function?
Asked Answered
C

3

78

I rarely see decltype(auto) but when I do it confuses me because it seems to do the same thing as auto when returning from a function.

auto g() { return expr; }
decltype(auto) g() { return expr; }

What is the difference between these two syntaxes?

Crustacean answered 26/1, 2014 at 20:59 Comment(0)
H
89

auto follows the template argument deduction rules and is always an object type; decltype(auto) follows the decltype rules for deducing reference types based on value categories. So if we have

int x;
int && f();

then

expression    auto       decltype(auto)
----------------------------------------
10            int        int
x             int        int
(x)           int        int &
f()           int        int &&
Hillside answered 26/1, 2014 at 21:3 Comment(9)
But what if I did auto&& x = 5 then it would be int&& but if I do decltype(auto) x = 5 it would still be int&&.Crustacean
@templateboy: no, the latter would just be int. Only xvalues become rvalue references.Hillside
@templateboy: If you're just declaring a variable, auto is by far more useful (e.g. if you have auto && for a universal reference). decltype is useful when you mainly want to operate with types (not variables), e.g. in traits that check if some expression has a certain type.Hillside
Does decltype(auto) also maintain cv-qualification?Crustacean
@templateboy: Yes, it's always the type of the expression, possibly with references added. If the expression is a CV-qualified value, that's retained. For details, see 7.1.6.2/4 ([dcl.type.simple]).Hillside
What about if f() returned an int. Would decltype((f(x))) return int &&?Reeder
@soandos: No, then it'd be int. Only xvalues, not prvalues, become rvalue references.Hillside
@KerrekSB Then the question would be when to use decltype(auto) and when just auto? Is there a rule of the thumb for each case?Filmy
@Zingam: Use auto when you want to return a prvalue, and decltype(auto) when you want to forward the returned expression preserving its value category. The latter is more subtle and needs careful thinking about, and usually comes up in generic code only. The former may reasonably be used in leaf code.Hillside
P
25

auto returns what value-type would be deduced of you assigned the return clause to an auto variable. decltype(auto) returns what type you would get if you wrapped the return clause in decltype.

auto returns by value, decltype maybe not.

Panties answered 26/1, 2014 at 21:5 Comment(0)
A
1

Simply put, when used as function return:

  • auto potentially drops cv-qualifiers and references.
  • decltype(auto) preserves cv-qualifier and reference-ness.

For example:

decltype(auto) func(int& x) // Equivalent to `auto& func(int& x)
{
return x;
}

decltype(auto) func(int&& x) // Equivalent to `auto&& func(int&& x)
{
return std::move(x);
}

decltype(auto) func(const int& x) // Equivalent to `const auto& func(int& x)
{
return x;
}

auto& func(const int& x) // Equivalent to `const auto& func(const int&x)
{
return x;
}

template <typename T>
auto func(T &&x) // Equivalent to `T func(T&& x)
{
return x;
} 

Argumentation answered 14/1 at 0:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.