Boost logo

Boost :

Subject: [boost] Call for interest - BOOST_AUTO_FUNCTION
From: Matt Calabrese (rivorus_at_[hidden])
Date: 2010-10-05 15:20:22


I've been noticing that a lot of times in 0x code I've found it useful to
create a very simple "auto function" macro that uses trailing return type
syntax with decltype with 1-liner functions that automatically repeats the
same expression in both the return type and the return statement.

#define AUTO_FUN( name, param_list, expression )
  \
auto name param_list -> decltype( expression ) { return expression; }

There are two big advantages to this. The first and most obvious one is that
it reduces redundancy when you have a 1-line function template which has a
difficult to deduce return type that you generally would use decltype on,
and the more subtle benefit is that since the exact expression is repeated
in the return type you automatically get "perfect-fit" SFINAE. By that I
mean it provides a quick way to SFINAE-out potential instantiations before
instantiating the implementation. Because of this, even though a return type
may be simple to deduce without decltype, the macro is still a valuable tool
since it can cause substitution to fail if the body of a function template
would fail to instantiate. You get very basic, automatic, syntax-only
concept checking for free. It's a simple macro, but I find that it gets lots
of use.

As an example:
 http://codepaste.net/iqzbiz

The above example is a simple "multi_cast" that chains several static_casts
in a row (the example code shows a potential use-case). The subtlety here is
that the return type is easily deducible without the need for decltype (the
return type would just be "TargetType"). Instead, the macro is used because
it causes substitution to fail if the body of the function would fail during
instantiation. So when using "multi_cast" here, If someone attempts to do a
cast where any of the intermediate types is not a valid conversion, rather
than getting a complicated error nested inside of several instantiations,
you get a single error message at the top-level call-site stating that there
is no match for the function call (well, at least it's a simple to read
error in gcc... *cough*). This works because if the body of any of the calls
would have an error, substitution would instead fail, meaning substitution
would fail for the caller, all the way back up to the top without any bodies
being instantiated. In other words, it's SFINAEs all the way down :|

I find this type of functionality to be very useful, particularly in
libraries. In fact, I find myself using it for just about all 1-line
function templates. Do others agree that this would be a worthwhile addition
to boost? Documentation should be quick to write up. The macro would of
course be renamed to something along the lines of BOOST_AUTO_FUNCTION

If anyone thinks multi_cast would be useful, let me know and I'll also spin
off a separate thread for that, though I'm tempted to think it's more of a
curiosity than something that would get much use.

-- 
-Matt Calabrese

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk