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

Suppose I have a function that combines two values. If I don't know anything about types, then basically I have to write my function twice; once in a valid return value and again as a return type specifier:

template <typename A, typename B> auto Add(const A& a, const B& b) ->std::decay<decltype(a + b)>::type { return a + b; } 

While this works, it is undesirable because it is difficult to read and difficult to maintain.

In C ++ 14, this will not be a problem, because we can remove the return type specifier (I'm not sure if this will decay, though ...). So far, I'm stuck with C ++ 11.

In my experience, when I look for a function in C ++ that has not yet made its way to the standard, but for which there is an obvious need, the Boost library usually has a solution. I looked through the documentation, but I did not find anything that could help me. The functions BOOST_AUTO_RETURN and BOOST_TYPEOF_TPL seem more aimed at providing C ++ 11 capabilities to C ++ 03 users.

Basically what I need is what performs the following functions:

 template <typename A, typename B> auto Add(const A& a, const B& b) { return a + b; // Deduce return type from this, like C++14 would } 

Is there some kind of functionality in the Boost library that I don’t know about (or an excellent trick in C ++ 11) that can allow me to refuse explicit -> decltype(...) after each type of automatic return? How will this be implemented?

+61
c ++ boost c ++ 11
Aug 15 '14 at 4:24
source share
2 answers

The only possible return type return function in C ++ 11 is the return type lambda. However, C ++ 11 restricts the use of lambda. It works:

 auto add = [](int a, int b) { return a + b; }; 

This is valid and defines add as a lambda that defines a member function operator() that returns an int . Since lambda doesn't capture anything, you can even write

 auto add = +[](int a, int b) { return a + b; }; 

to make add regular function pointer: it gets the type int(*)(int, int) .

However, C ++ 11 does not allow parameter types to be specified as auto or to prevent add defined as a template variable, so you cannot use this to generally infer the type of the return value. An attempt to wrap it in a template class failed:

 template <typename A, typename B> struct S { static auto add = [](A a, B b) { return a + b; }; }; // invalid 

It is not add to initialize add in a class, and you cannot use auto if a member is not initialized in the class. Also, even if it worked, it would not be possible to subtract A or B , which seems to be more than what you need.

Given these limitations, I see no alternative but to repeat the expression. However, you can hide the repetition in a trivial macro.

 #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 an option noted by Mark Gliss,

 #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 little cleaner.

There might be something like this in Boost, I don't know. Despite the triviality, Boost seems redundant here.

+26
Aug 16 '14 at 12:26
source share

There is a Pythy library that tries to emulate this syntax. However, it will only work on clang. This does not work on gcc due to these errors here and here . They can be fixed for gcc 4.9, but if you are using gcc 4.9 you can use automatic return types anyway.

+5
Aug 17 '14 at 21:14
source share



All Articles