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;
}
The following code in C++11:
auto function() -> int
{
return 0;
}
Is equal to the following code in C++03:
int function()
{
return 0;
}
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.
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?
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.
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.
In C++14, you can just use auto as a return type.
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):
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";
}
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).
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With