Using auto to deduce the return type of a function in C++11 is way too verbose. First, you have to use the so-called trailing return type and second, you have to specify the return type in a decltype expression. You have to read the expression auto sum(T t, T2 t2) -> decltype(t + t2) in the following way.
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.
decltype(auto) is primarily useful for deducing the return type of forwarding functions and similar wrappers, where you want the type to exactly “track” some expression you're invoking.
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.
The only possible deduced function return type in C++11 is the return type of a lambda. C++11 restricts the use of lambdas, though. This works:
auto add = [](int a, int b) { return a + b; };
This is valid, and defines add
as a lambda that defines an operator()
member function that returns int
. Since the lambda doesn't capture anything, you can even write
auto add = +[](int a, int b) { return a + b; };
to make add
a regular pointer-to-function: it gets type int(*)(int, int)
.
However, C++11 doesn't allow parameter types to be specified as auto
, nor to let add
be defined as a template variable, so you cannot use this to generically deduce a return type. An attempt to wrap it up in a template class fails:
template <typename A, typename B>
struct S { static auto add = [](A a, B b) { return a + b; }; }; // invalid
It is invalid to initialise add
in-class here, and you cannot use auto
unless the member is initialised in-class. Besides, even if it did work, it wouldn't allow deduction of A
or B
, which seems to be more what you're after.
Given those limitations, I don't see any alternative but to repeat the expression. You could hide the repetition in a trivial macro, though.
#define AUTO_RETURN(func, ...) auto func -> decltype(__VA_ARGS__) { return __VA_ARGS__; }
template <typename A, typename B>
AUTO_RETURN(add(A a, B b), a + b)
Or the variant pointed out by Marc Glisse,
#define RETURNS(...) noexcept(noexcept(__VA_ARGS__)) -> decltype(__VA_ARGS__) { return __VA_ARGS__; }
template <typename A, typename B>
auto add(A a, B b) RETURNS(a + b)
which looks a bit cleaner.
There might be something like this in Boost already, I don't know. Regardless, given the triviality, Boost seems overkill here.
There is a library Pythy that tries emulate this syntax. However, it will only work on clang. It doesn't work on gcc due to these bugs here and here. They may be fixed for gcc 4.9, but if you are using gcc 4.9 you can use auto return types, anyways.
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