Re: Ideal min/max
Sorry for the delayed response....
Andrei Alexandrescu (See Website For Email) wrote:
Bob wrote:
Jason Hise wrote:
I remember reading about an elegant solution mentioned by Andrei
Alexandrescu for generating ideal min and max templates, but I can't
find where I read it. The solution involved some sort of double
nesting of the question colon operator in order to determine the
correct return type. I believe it was mentioned in passing in an
article of his on some other subject. Does anyone know what this
solution was or where I could find it?
I made a brief mention about Andrei's and my solution in the comment
section of my article "Conditional Love" on The C++ Source:
http://www.artima.com/cppsource/foreach.html
Perhaps that's what you're thinking of.
Andrei used a reasonably liberal interpretation of "elegant".
Good point :o).
The solution was reasonably elegant and not that much code, as long
as it was built on his Loki library. And the tools employed
from that library are actually based on both macro and template
trickery.
In any event, an online version of the article is at
http://www.ddj.com/dept/cpp/184403774
Jason is referring to a different solution, which was developed by Eric
Niebler following an idea of mine. (He did most of the work.) I'm not
sure whether he published it yet. The basic idea is this:
#define MIN(a, b) min_impl(true ? (a) : (b), false ? (a) : (b))
Then all of a sudden you have the macro streamline the types for you
exactly as operator?: would, but without the double evaluation. So you
got the best of both worlds. Given that min_impl's arguments will be of
the same type, all you have to do then is to implement two overloads:
template <class T>
const T& min_impl(const T& a, const T& b) { ... }
template <class T>
T& min_impl(T& a, T& b) { ... }
A lingering problem is that the first overload is selected for rvalues,
too, which means that somebody could save a dud object by writing const
int& dud = MIN(4, 5); Eric went ahead and solved that problem, too, at
the expense of implementation simplicity: the code size and complexity
blow up.
Actually, the full, 100% standard compliant solution is not very
complicated at all, and you can see it here: http://tinyurl.com/j4b23.
The complexity comes from finding work-arounds for broken compilers, and
sadly, regarding the tricks I use, all compilers are broken at the
moment. At http://tinyurl.com/ep8rt, in the file minmax_macro.zip, you
can find a version that works on gcc, msvc and edg-based compilers.
In the end I'm more fond of the approach of my older article because it
can (as a poster mentioned) employ the semantics of min and max to
refine the result type (e.g., min of unsigned int and unsigned char is
unsigned char). The version above is most faithful to what a < b ? a : b
would do, and that's nice, too.
But, I agree: if min and max are this complicated to implement properly,
that becomes more of an embarrassment than a interesting challenge.
Unfortunately, I seem to recall from an email exchange that the version
based on rvalue references is still not as trivially simple as it ought
to be.
But a solution that uses rvalue references *and* return type deduction
is about as simple as falling off a bar stool. :-)
--
Eric Niebler
Boost Consulting
www.boost-consulting.com
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]