Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to ignore the trailing return type feature of c++11 in favor of the function return type deduction feature of c++14?

When I skip the return type of an expression

The following code in C++11:

auto function(X x, Y y) -> decltype(x + y)
{
    return x + y;
}

Is equal to the following code in C++14:

decltype(auto) function(X x, Y y)
{
    return x + y;
}

But additionally it is possible to deduce the return type without decltype rules in C++14:

auto function()
{
    return 0;
}

When I know what the return type is exactly

The following code in C++11:

auto function() -> int
{
    return 0;
}

Is equal to the following code in C++03:

int function()
{
    return 0;
}

A strange example that should never happen

The following code in C++11:

auto function(X x, Y y) -> decltype(x * y)
{
    return x; // Yeah! return x with the type of x * y expression!
}

Is equal to the following code in C++14:

decltype(auto) function(X x, Y y)
{
    return static_cast<decltype(x * y)>(x);
}

Please correct me, if the above code is wrong and does not work as expected.

EDIT, According to the comment (Yakk): They are not really equal, the first one (C++11 example) is an implicit cast while the second one (the static_cast of C++14 example) is an explicit cast.

Conclusion

As you can see, I can do everything without using the alternative function syntax feature of C++11. Am I correct? Can I completely forget about it without getting any technical problem?

In general, the following syntax can be avoided:

auto function() -> TYPE
{
    return 0;
}

In favor of the following syntax:

TYPE function() // TYPE can be: auto, decltype(auto), or ...
{
    return 0;
}

Did I forget any usage of the trailing return type feature of C++11 that is not possible with the function return type deduction feature of C++14?

like image 828
Sadeq Avatar asked Aug 16 '14 14:08

Sadeq


People also ask

Why use trailing return type c++?

The trailing return type feature removes a C++ limitation where the return type of a function template cannot be generalized if the return type depends on the types of the function arguments.

Which C++ added feature of Auto for return type of function?

C++: “auto” return type deduction The “auto” keyword used to say the compiler: “The return type of this function is declared at the end”. In C++14, the compiler deduces the return type of the methods that have “auto” as return type.

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

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


1 Answers

There are three important differences between a function using automatic-return-type-deduction and one with an explicit return-type (even if that is computed):

  1. You cannot do SFINAE on the computability of the return-type if you do not explicitly specify it: You get a hard error instead. Why? Because SFINAE only works with the declaration, not the definition of functions (SFINAE: (template-argument) substitution-failure is not an error).

    automatic-return-type-deduction, no SFINAE
    SFINAE, but no automatic return-type deduction

    #include <iostream>
    int doit(int x, ...) { return x; }
    template<class X, class Y> auto doit(X x, Y y)
    #ifdef TRAILING_RETURN_TYPE
    -> decltype(doit(x) + doit(y))
    #endif
    { return doit(x) + doit(y); }
    
    int main() {
        std::cout << doit(1, nullptr) << "\n";
    }
    
  2. At the moment, you cannot forward-declare a function with its actual return-type, if the definition uses automatic return-type-deduction, nor can it be virtual. (Explicit rule)

    7.1.6.4 auto specifier [dcl.spec.auto]

    13 Redeclarations or specializations of a function or function template with a declared return type that uses a placeholder type shall also use that placeholder, not a deduced type.
    14 A function declared with a return type that uses a placeholder type shall not be virtual (10.3).

  3. Only functions with automatic return-type deduction can return a lambda, as there is no other way to get its type.

     auto foo() { return [] {}; }
    

Link to the proposal, which was incorporated into the draft for C++14:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3638.html

like image 174
Deduplicator Avatar answered Sep 20 '22 15:09

Deduplicator