|
Boost : |
From: Guillaume Melquiond (guillaume.melquiond_at_[hidden])
Date: 2004-02-24 05:14:58
Le mar 24/02/2004 à 10:15, Eric Niebler a écrit :
> Guillaume Melquiond wrote:
> > How did you deal with occurrences of min and
> > max that rely on ADL (sorry if that is not the correct term)? Or did you
> > handle only explicitly qualified calls std::min and std::max?
> >
> > I'm asking because the Interval library relies on this kind of construct
> > in order to deal with built-in types (like int, float, etc) and
> > user-defined types (their min and max are found by Koenig lookup).
>
>
> Hmmm ... I was aware of the theoretical possibility of this problem, but
> I didn't know there was actual boost code relying on ADL with
> std::min/std::max.
If there is a better way than Koenig lookup to allow the use of both
std-defined and user-defined min and max (I'm only speaking about min
and max here, but the library also has the same problem with abs, sin,
sqrt, etc), I can change the library. Unfortunately I don't know of such
a way (except requiring the user to define its own versions of the
functions directly in the std namespace).
Is the interval library the only Boost library allowing min and max
functions to be used with user-defined types? How is this problem dealt
with in the other libraries.
> And the regression test with VC7.1 didn't expose this
> problem. (Shortcoming of vc7.1 or the interval regression tests?)
Yes it is a shortcoming of the interval regression tests (that doesn't
mean it isn't also a shortcoming of VC7.1). I only test for things that
could break in the current code, not for things somebody else could
change afterward :-).
> Getting the interval library to play nice with the min/max macros will
> take some work. Considering your code:
>
> template< class T >
> void f(T const &a, T const &b) {
> using std::min; min(a,b);
> }
>
> It *might* compile in the presence of the min() macro but it would
> likely do the wrong thing.
I don't remember exactly what the original problem was. Was it supposed
to happen only with some compilers? Or with all the compilers that were
using Microsoft headers?
> It's unfortunate in this case that (min)(a,b)
> turns off ADL. (Out of curiosity, is there a case where it's not
> unfortunate? Ever since this language "feature" was brought to my
> attention last year, I have wondered about it.)
>
> The obvious answer is to #undef min and max for the interval library, or
> at least #pragma push_macro/pop_macro for the compilers that support
> that. Yech.
Wasn't there the idea of adding prefix and suffix headers to Boost? If
it was undef'd or pragma_push'd for all the libraries, it would avoid
changing these 800 occurrences. Or am I missing something?
> Another thought just occured to me. Consider:
>
> #define BOOST_EMPTY
> template< class T >
> void f(T const &a, T const &b) {
> using std::min; min BOOST_EMPTY (a,b);
> }
>
> This seems to be enough to prevent min() macro substitution, and it
> would preserve ADL. I checked with VC6, VC7.1, gcc (cygwin) and with
> Comeau Online, and they all like it. Will this work on other compilers too?
It's ugly. But I suppose we could use a boost_min macro to avoid
cluttering the code (if it still works).
Regards,
Guillaume
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk