Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can Boost be used to achieve C++14-style auto return types?

Tags:

c++

c++11

boost

People also ask

How do I return an auto in C++?

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.

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.

What does decltype auto do?

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.

What is trailing return type in 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.


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.