web-dev-qa-db-fra.com

utilisation non valide d'une fonction membre non statique

J'ai quelque chose comme ça:

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

La méthode Foo::Count Doit utiliser std::lower_bound() pour rechercher un élément dans vector<Bar> En fonction d'une paire de deux chaînes. Maintenant la partie qui ne fonctionne pas. Pour lower_bound() je fournis la méthode comparator(). Je pensais que ça allait, mais g ++ dit:

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

Et la méthode Count() doit rester const...

Je suis assez nouveau en C++ parce que je suis obligé de l'apprendre.

Des idées?

18
Nash

Vous devez faire Foo::comparator statique ou envelopper dans un std::mem_fun objet de classe. Ceci est dû au fait que lower_bounds s'attend à ce que le comparateur soit une classe d'objet dotée d'un opérateur d'appel, comme un pointeur de fonction ou un objet foncteur. De même, si vous utilisez C++ 11 ou une version ultérieure, vous pouvez également faire ce que dwcanillas suggère et utiliser une fonction lambda. C++ 11 a aussi std::bind aussi.

Exemples:

// 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 ...; });
8
Matthew

La solution la plus simple consiste à rendre la fonction de comparaison statique:

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

Lors de son invocation dans Count, son nom sera Foo::comparator.

Dans l’état actuel des choses, il n’a pas de sens d’être une fonction membre non statique, car elle n’utilise aucune variable membre de Foo.

Une autre option consiste à en faire une fonction non membre, en particulier s'il est logique que ce comparateur puisse être utilisé par un code autre que Foo.

16
M.M

Vous devez passer un pointeur this pour indiquer à la fonction quel objet travailler, car il repose sur celui-ci, par opposition à une fonction membre static.

2
edmz