Not2 STL отрицатель - PullRequest
       23

Not2 STL отрицатель

1 голос
/ 07 декабря 2009

Изучение STL Я пытался свести на нет функтор с not2, но с возникшими проблемами. Вот пример:

#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;

}

Последняя строка кода не будет компилироваться с использованием g ++. Вероятно, глупая ошибка, но где?

Ответы [ 4 ]

5 голосов
/ 07 декабря 2009
struct  mystruct : binary_function<int,int,bool> {
        bool operator() (int i,int j) const // add a const here
            { return i<j; }
};

Причина:

В этой строке:

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

not2 (mystruct ()) вернет std::binary_negate:

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

В std :: binary_negate вызывающим оператором является постоянная нестатическая функция-член

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
         }
};
4 голосов
/ 07 декабря 2009

Изменение:

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

тоже:

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

Есть два скрытых вопроса по вашему вопросу в комментариях:

1) Почему я должен добавить const к методу:

Вы должны использовать const, так как элементы объекта не изменены.
Создать правильные методы очень просто. Добавление const-корректности к методам после факта может стать настоящим ужасом, так как const все больше и больше проникает в вашу иерархию классов.

2) Почему при добавлении const к методу он компилируется.

Конструктор объекта, возвращаемого not2 (), принимает константную ссылку на ваш объект в качестве параметра. Это довольно распространенный метод, но он требует, чтобы все используемые вами методы также были постоянными.

2 голосов
/ 07 декабря 2009
bool operator()  (int i,int j) const{ return i<j; }

const отсутствует в вашем функторе

2 голосов
/ 07 декабря 2009

Оператор mystruct () должен выглядеть следующим образом:

bool operator() (int i, int j) const // note the const
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...