Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ template auto return type with arrow-notation require decltype?

C++11 introduced the arrow-notation(don't know the name) for return types in functions:

template <typename T>
auto fun(T&& a) -> decltype(bar(a)){ ... }

but according to scott meyer, using auto as the return type by itself will drop all const and reference qualifiers(because it follows the same pattern as template deduction), and therefore the idiomatic way is to do decltype(auto) to keep all qualifiers on top of the type.

However, in this context, is auto inferred to be decltype(bar(a))? Then would decltype(auto) be decltype(decltype(bar(a)))? Would that be redundant?

like image 320
OneRaynyDay Avatar asked Jul 31 '18 17:07

OneRaynyDay


People also ask

What is the return type of decltype?

If the expression parameter is a call to a function or an overloaded operator function, decltype(expression) is the return type of the function. Parentheses around an overloaded operator are ignored. If the expression parameter is an rvalue, decltype(expression) is the type of expression .

Can auto be a return type?

In C++14, you can just use auto as a return type.

Can you use auto as a return type in C++?

The return type, which specifies the type of the value that the function returns, or void if no value is returned. In C++11, auto is a valid return type that instructs the compiler to infer the type from the return statement. In C++14, decltype(auto) is also allowed.


2 Answers

When you have a trailing return type, the auto keyword appears purely as an element of notation. The return type becomes whatever type comes after the ->. No type deduction is performed. This is simply how function declarations with a trailing return type are written. Auto return type deduction only happens when you do not have a trailing return type, i.e., auto is used as a placeholder return type with no -> … at the end of your function declarator.

like image 143
Michael Kenzel Avatar answered Oct 21 '22 20:10

Michael Kenzel


Assuming int& bar(); (or using trailing return type syntax auto bar() -> int&;),

you may declare several functions:

  • int& f1(); or auto f1() -> int&;.
  • decltype(bar()) f2(); or auto f2() -> decltype(bar());. (return type is int&). decltype allows SFINAE usage for template function.
  • decltype(auto) f3() { return bar(); } Definition needed (deduced as int&) (No SFINAE).
  • auto f4() { return bar(); } Definition needed (deduced as int) (No SFINAE).

decltype(expression) is a type, and decltype(type) is invalid, so decltype(decltype(expression)) is invalid too.

like image 30
Jarod42 Avatar answered Oct 21 '22 19:10

Jarod42