Boost logo

Boost :

From: Ian Whittley (imw_at_[hidden])
Date: 2002-05-16 09:53:58


Hi,

I sent the following email to Scott Meyers a few months and wondered if it
might be of interest to the Boost community. I apologize in advance if, as
a new subscriber to the list, i am just reinventing the wheel here.

Ian Whittley
Senior Research Associate
University of East Anglia

"Hi,

I've been using overloaded logical operators for a while in my code and so
was surprised to see 'item 7' in 'More Effective C++' speak out against
them. The following code seems, to me at least, to provide a perfectly safe
way to overload these operators:

        template<class T, class U>
        class or_fn
        {
                T a;
                U b;
        public:
                or_fn(T& _a, U& _b):a(_a), b(_b){}
                template<class V> bool operator()(V& i){ return a(i) || b(i); }
        };
        
        template<class T, class U>
        class and_fn
        {
                T a;
                U b;
        public:
                and_fn(T& _a, U& _b):a(_a), b(_b){}
                template<class V> bool operator()(V& i){ return a(i) && b(i); }
        };

        template<class T, class U> inline or_fn<T,U> operator||(T& a, U& b){
return or_fn<T,U>(a,b); }
        template<class T, class U> inline and_fn<T,U> operator&&(T& a, U& b){
return and_fn<T,U>(a,b); }

It allows short-circuited evaluation and provides an intuitive interface to
what can otherwise be rather confusing code - as given on page 187 of
Effective STL (deliberately of course):

        vector<int>::iterator i = find_if(a.begin(),a.end(),
bind2nd(greater<int>(),x) && bind2nd(less<int>(),y) );

Okay, so the bind2nd's might still confuse people but they can easily be
removed. The method i use (which i guess is pretty standard) takes the
following form:

        template<class T>
        class greater_than_fn
        {
                T a;
        public:
                greater_than_fn(T _a):a(_a){}
                bool operator()(T b){ return b > a; }
        };
        template<class T> inline greater_than_fn<T> greater_than(T a){ return
greater_than_fn<T>(a); }

This allows the code to be written as:

        vector<int>::iterator i = find_if(a.begin(),a.end(), greater_than(x) &&
less_than(y) );

And i defy any C++ programmer to misunderstand that code!

Anyway, thanks for your time. I hope the code above proves interesting
although i doubt i'm the first to bring it to your attention.

Ian Whittley
Senior Research Associate
University of East Anglia "


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