web-dev-qa-db-ja.com

非静的メンバー関数の無効な使用

私はこのようなものを持っています:

_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()を使用して、2つの文字列のペアに従って_vector<Bar>_の要素を見つける必要があります。今、動作しない部分。 lower_bound()にメソッドcomparator()を提供しています。私はそれが大丈夫だと思ったが、g ++は言う:

_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++を学ぶことを余儀なくされているので、私はC++を初めて使用します。

何か案は?

18
Nash

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

最も簡単な修正方法は、コンパレーター関数を静的にすることです。

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

Countで呼び出すと、その名前はFoo::comparator

現在の方法では、Fooのメンバー変数を使用しないため、非静的メンバー関数としては意味がありません。

別のオプションは、特にこのコンパレーターがFooだけでなく他のコードで使用される可能性がある場合、非メンバー関数にすることです。

16
M.M

thisメンバ関数ではなく、それに依存するため、どのオブジェクトで作業するかを関数に伝えるために、staticポインタを渡す必要があります。

2
edmz