
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