2015-03-26 3 views
6

У меня есть что-то вроде этого:неправильное использование нестатической функции члена

class Bar 
     { 
     public: 
     pair<string,string> one; 
     std::vector<string> cars; 
     Bar(string one, string two, string car); 
     }; 

class Car 
     { 
     public: 
     string rz; 
     Bar* owner; 
     Car(string car, Bar* p); 
     }; 

class Foo 
     { 
     public: 
      Foo (void); 
      ~Foo (void); 
      int Count (const string & one, const string & two) const; 
      int comparator (const Bar & first, const Bar & second) const;    
      std::vector<Bar> bars; 
     }; 

int Foo::comparator(const Bar & first, const Bar & second) const{ 
    return first.name < second.name; 
} 

int Foo::Count (const string & one, const string & two) const{ 
    int result=0; 
    Bar mybar = Bar(one, two, ""); 
    std::vector<Bar>::iterator ToFind = lower_bound(bars.begin(), bars.end(), mybar, comparator); 
    if (ToFind != bars.end() && ToFind->one == mybar.one){ 
    result = ... 
    } 
    return result; 
} 

Метод Foo::Count следует использовать std::lower_bound() найти элемент в vector<Bar> в соответствии с парой двух строк. Теперь часть, которая не работает. До lower_bound() Я предоставляю метод comparator(). Я думал, что это было хорошо, но г ++ говорит:

c.cpp: In member function ‘int Foo::Count(const string&, const string&) const’: 
c.cpp:42:94: error: invalid use of non-static member function 
std::vector<Bar>::iterator ToFind = lower_bound(bars.begin(), bars.end(), mybar, comparator); 

И метод Count() должен остаться const ...

Я совершенно новой для C++, потому что я вынужден учиться.

Любые идеи?

+0

Почему именно эта функция не статична? – chris

+0

Какой? Мне не разрешено изменять объявление функции Count() – Nash

ответ

3

Вы должны сделать Foo::comparator статическим или обернуть его в объект класса std::mem_fun. Это связано с тем, что lower_bounds ожидает, что сравнитель будет классом объекта, который имеет оператор вызова, например, указатель функции или объект-функтор. Кроме того, если вы используете C++ 11 или более поздней версии, вы также можете сделать то, что предлагает dwcanillas и использовать функцию лямбда. C++ 11 также имеет std::bind.

Примеры:

// Binding: 
std::lower_bounds(first, last, value, std::bind(&Foo::comparitor, this, _1, _2)); 
// Lambda: 
std::lower_bounds(first, last, value, [](const Bar & first, const Bar & second) { return ...; }); 
+1

Или использовать функцию лямбда. – dwcanillas

+0

Хорошо, теперь я понял. Большое вам спасибо! – Nash

+1

Добро пожаловать. Я бы сделал так, чтобы функция сравнения была статичной, поскольку она не имеет доступа к классу. –

0

Вы должны пройти this указатель, чтобы сообщить функции какой объект для работы, потому что опирается на том, что в отличие от функции в static члена.

6

Самым простым способом исправить это сделать функцию компаратора быть статичным:

static int comparator (const Bar & first, const Bar & second); 
^^^^^^ 

При вызове его в Count, его имя будет Foo::comparator.

То, как у вас есть это сейчас, не имеет смысла быть нестатической функцией-членом, поскольку она не использует никаких переменных-членов Foo.

Другой вариант - сделать его функцией, не являющейся членом, особенно если имеет смысл, что этот компаратор может использоваться другим кодом, кроме Foo.