2013-08-29 2 views
3

У меня есть класс с методом, который я также хотел бы использовать в качестве предиката.Определить предикат внутри класса

class MyClass { 
    bool ParticleHasAncestor(const Particle &particle, int id) const; 

    class AncestorPredicate { 
    int mId; 
    public: 
    AncestorPredicate(int idCode) : mId(idCode) { } 
    bool operator()(const Particle &particle) const { return ParticleHasAncestor(particle, mId); } 
    }; 
}; 

Однако компилятор жалуется не будучи в состоянии использовать ParticleHasAncestor() без экземпляра MyClass. Нужно ли использовать класс друзей? Или есть лучшее решение для этого?

Я не использую C++ 11, поэтому не могу использовать лямбда-функции.

Обновление:ParticleHasAncestor() не может быть статическим, так как в нем используются члены MyClass.

ответ

0

В отличие от Java, в C++ внутренний класс не имеет указателя на внешний класс.

MyClass::AncestorPredicate, не имеет экземпляра MyClass, и вы не можете вызывать нестатический метод MyClass без указателя на объект этого класса.

У вас есть два варианта:

Первый. Сделать MyClass::ParticleHasAncestor статический метод MyClass:

class MyClass { 
    static bool ParticleHasAncestor(const Particle &particle, int id); 

    class AncestorPredicate { 
     int mId; 
    public: 
     AncestorPredicate(int idCode) : mId(idCode) { } 
     bool operator()(const Particle &particle) const 
     { 
      return MyClass::ParticleHasAncestor(particle, mId); 
     } 
    }; 
}; 

Второй. Создание экземпляра MyClass и передать указатель на AncestorPredicate, так что вы можете вызвать ParticleHasAncestor на этом объекте: «... но это не может быть` const` затем»

class MyClass { 
    bool ParticleHasAncestor(const Particle &particle, int id) const; 

    class AncestorPredicate { 
     int mId; 
     const MyClass* obj; 
    public: 
     AncestorPredicate(int idCode, const MyClass* _obj) : mId(idCode), obj(_obj) { } 
     bool operator()(const Particle &particle) const 
     { 
      return obj -> ParticleHasAncestor(particle, mId); 
     } 
    }; 
}; 
+0

Если я использую второй вариант, могу ли я использовать предикат в MyClass, таким образом: 'electron.erase (std :: remove_if (electron.begin(), electron.end(), std :: not1 (AncestorPredicate (higgs_id, this)())), electron.end()) ' –

+0

@DavidHall Да, вы можете –

+0

Примечание: У меня не должно быть дополнительных скобок в приведенном выше. Так что просто 'AncestorPredicate (higgs_id, this)' without trailing '()' –

5

Сделать этот предикат статическим методом. Но тогда это не может быть const.

+1

Не то, чтобы это нужно. 'const' не имеет смысла в функции' static' member. – Angew

+1

Если 'ParticleHasAncestor' был статичным, он также мог бы сделать следующий шаг и подумать об использовании' std :: bind2nd', чтобы он мог полностью удалить помощника «AncestorPredicate». –

+0

Я не могу сделать 'ParticleHasAncestor()' static, поскольку это зависит от членов MyClass. –

Смежные вопросы