What is the purpose of a placeholder type in a trailing-return-type?

  • A+

According to [dcl.fct]/2 the snippet below is legal. GCC and clang compile and execute the code,

#include <iostream> int i = -1; auto f()->auto&& { return i; } int main(){     f() = 2;     std::cout << i << '/n'; } 



But what is the purpose of allowing this in C++?

In the example above, one could get the same result just by replacing the trailing-return-type with int&. In other words, I'm looking for an example where the trailing-return-type containing a placeholder type would be meaningful.


You can make an argument about consistency: you can stick other types as trailing return types, why not placeholders?

auto f() -> int&  { return i; } auto f() -> auto& { return i; } 

You can make an argument about utility: the return type for lambdas looks like a trailing return type and has no other place to put a placeholder type, so you have to allow it for lambdas anyway, so might as well allow it for functions?

auto f = []() -> int&  { return i; }; auto f = []() -> auto& { return i; }; 

You can make an argument about code formatting. The trailing return type allows for consistent way to declare functions that always works for all cases, so just lining it up:

auto g(auto x)     -> decltype(f(x)) { ... } // using trailing for parameter auto Cls::member() -> type { ... }  // using trailing for scope (to find Cls::type) auto h(auto x)     -> auto& { ... }  // using trailing for formatting 

There might be other arguments. But in short, it's easy to allow and clearly has merit.


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: