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?

戏子无情 提交于 2020-01-02 00:56: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?


回答1:


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) << std::endl;
    }
    
  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++1y:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3638.html



来源:https://stackoverflow.com/questions/25341378/is-it-possible-to-ignore-the-trailing-return-type-feature-of-c11-in-favor-of-t

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!