Fureeish
Fureeish

Reputation: 13424

Does decltype(auto) make trailing return type obsolete?

There have been many, many, many questions and answers regarding the trailing return type, auto return type deduction and the very useful decltype(auto). But I failed to find an answer to whether the trailing return type is needed at all since we have decltype(auto). Are there cases that the trailing return type solves, where decltype(auto) either cannot be used or doesn't work (gives unexpected / incorrect results) and the trailing return type was needed in the first place?

Upvotes: 4

Views: 510

Answers (2)

Jarod42
Jarod42

Reputation: 217145

decltype(auto) (and more generally deduced return type) and trailing return type are orthogonal features.

You can have:

  • decltype(auto) f() {}
  • auto f() -> decltype(auto) {}

Trailing return type

trailing return type is fine especially to have access to context we don't have before the function name

  • as for template:

    template <typename T>
    auto f(T x) -> decltype(bar(x));
    

    versus

    template <typename T>
    decltype(bar(std::declval<T&>())) f(T x);
    
  • or for dependent name in class:

    auto C::begin() -> iterator;
    

    versus

    C::iterator C::begin();
    

The only place where it is required is for lambda (if you have/want to specify return type explicitly):

  • []() -> some_type {/*...*/}
  • []() -> auto {/*...*/} (which is equivalent to []() {/*...*/})
  • []() -> decltype(auto) {/*...*/}

Case when we have to defining return type of lambda is when it should return reference type.

Deduced return type

Done with decltype(auto) and auto.

decltype(auto) and auto deduction type differs, mostly as T&& and T.

Deduced return type requires definition of the body.

They also doesn't allow SFINAE, as there are no substitution.

Upvotes: 5

user7860670
user7860670

Reputation: 37513

The trivial example would be a situation when you want to invoke function before it is defined and returned type is deduced:

decltype(auto) bar(); // doesn't help

decltype(auto) foo() { bar(); } // error: returned type of `bar` is unknown

decltype(auto) bar() { foo(); }

Upvotes: 6

Related Questions