tags:

views:

127

answers:

4
+1  Q: 

not2 stl negator

Hi, Studying STL I have tried to negate a functor with not2 but encontered problems. Here is the example:

#include <iostream>
#include <vector>
#include <functional>
#include <algorithm>
using namespace std;
struct  mystruct : binary_function<int,int,bool> {
 bool operator() (int i,int j) { return i<j; }
};

template <class T>
class generatore 
{
public:
 generatore (T  start = 0, T  stp = 1) : current(start), step(stp)
 { }
 T  operator() () { return current+=step; }
private:
 T  current;
 T  step;
};


int main () {
 vector<int> first(10);

generate(first.begin(), first.end(), generatore<int>(10,10) ); 
cout << "Smallest element " << *min_element(first.begin(), first.end(),mystruct() ) << endl;
 cout << "Smallest element:  " << *max_element(first.begin(), first.end(),not2(mystruct())) << endl;

}

Last line of code wil not compile using g++. Probably a stupid error but where ?

+4  A: 

Change:

bool operator() (int i,int j) { return i<j; }

too:

bool operator() (int i,int j) const { return i<j; }

There are two implicit question on your question in the comments:

1) Why should I add const to the method:

You should use const as no members of the object are changed.
Creating methods const correct is easy. Adding const correctness to methods after the fact can become a real nighmare as the const propogates further and further into your class hierarchy.

2) Why adding const to the method makes it compile.

The constructor of the object returned by not2() is taking a const reference to your object as a parameter. This is a relatively common technique, but does require that any methods that you use are also const.

Martin York
THANKS A LOT to all ! It works nicely now !.... Ahem... WHY should it be const ? (Note that without the not2 was working even before....)
GBBL
+2  A: 

mystruct operator() should look like this:

bool operator() (int i, int j) const // note the const
Nikola Smiljanić
+5  A: 
struct  mystruct : binary_function<int,int,bool> {
        bool operator() (int i,int j) const // add a const here
            { return i<j; }
};

The reason:

In this line:

cout << "Smallest element:  " << *max_element(first.begin(), first.end(),not2(mystruct())) << endl

not2(mystruct()) will return a std::binary_negate:

template<class AdaptableBinaryPredicate>
binary_negate<AdaptableBinaryPredicate> not2( P const& pred ) {
        return binary_negate<AdaptableBinaryPredicate>(pred);
}

In std::binary_negate, the calling operator is a const non-static member function

template <class AdaptableBinaryPredicate>
class binary_negate
        : public binary_function
                     <typename AdaptableBinaryPredicate::first_argument_type
                     ,typename AdaptableBinaryPredicate::second_argument_type
                     ,bool>
{
        AdaptableBinaryPredicate pred_;
public:
        explicit binary_negate ( const AdaptableBinaryPredicate& pred )
                : pred_ (pred) {} // holds the original predication

         bool operator() (const typename Predicate::first_argument_type& x,
                          const typename Predicate::second_argument_type& y
                         ) const  // the calling operator is const
         { return !pred_(x,y);    // call original predication and negate it!

           // the calling operator of binary_negate is const 
           //   so pred_ in this member has const qualify
           //   and the calling operator of pred_ must be const
         }
};
OwnWaterloo
+2  A: 
bool operator()  (int i,int j) const{ return i<j; }

const missing in your functor

aJ