Boost logo

Boost :

From: Paul Mensonides (pmenso57_at_[hidden])
Date: 2004-02-29 01:13:41


> [mailto:boost-bounces_at_[hidden]] On Behalf Of Thomas Witt

> Thanks Paul. But I do understand the reason why we need to
> disable macro
> expansion (at least I think so).

Sorry, I misunderstood.

> I was referring to the following sentence
>
> o Use boost::std_min(a,b) if you do require
> argument-dependent
> look-up. boost::std_min() delegates to std::min().
>
> I can't see where ADL comes into play here.

You're right, that only allows for overloading in namespace std (which is
illegal) and explicit specialization of std::min (which is not). ADL only comes
into play if boost::std_min() delegates to unqualified min(). If it does that,
it *must* be looked up either in the boost namespace, the function scope, or via
ADL. The surrounding context of the invocation no longer exists for lookup
purposes unless it happens to be found via ADL (ignoring the min macro):

#include <algorithm>

namespace abc {

template<class T> inline const T& delegate_min(const T& x, const T& y) {
    // using std::min;
    return min(x, y)
}

} // abc

inline int min(int x, int y) {
    return x < y ? x : y;
}

int main() {
    min(1, 2); // okay
    abc::delegate_min(1, 2); // error
    return 0;
}

This kind of solution enables ADL (especially if you introduce std::min with a
using declaration as a fallback), but it still ignores local context which makes
it different than direct a direct call to unqualified min(). The only way to
"have-your-cake-and eat-it-too" in the presence of macros like min/max is to
prevent them from expanding manually with BOOST_PREVENT_MACRO_SUBSTITUTION.

int main() {
    using std::min;
    min BOOST_PREVENT_MACRO_SUBSTITUTION(1, 2);
    return 0;
}

This yields ADL and local context (which includes std::min if necessary).

Regards,
Paul Mensonides


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