Не могу передать указатель на функцию производного класса в базовый класс - PullRequest
2 голосов
/ 10 января 2012

Я пытаюсь передать функцию из производного класса в функцию базового класса, которая ожидает указатель на функцию, но я получаю ошибку компилятора.

[BCC32 Error] E2034 Cannot convert 'void (Bar::*)(int)' to 'void (Foo::*)(int)'

Полагаю, это так, как задумано, но есть ли способ обойти это, не включая неприятное кастинг? Может ли boost::bind помочь мне здесь?

#define CALL_MEMBER_FN(object,ptrToMember)  ((object).*(ptrToMember))

class Foo
{
public:
  typedef void (Foo::*FFunc)(int i);

  void test(FFunc f)
  {
    CALL_MEMBER_FN(*this,f)(123);
  }

  void barf1(int i) {};
};

class Bar : public Foo
{
public:
  void barf2(int i) {};
};

void ffff()
{
  Foo f;
  f.test(Foo::barf1); // works

  Bar b;
  b.test(Bar::barf1); // works
  b.test(Bar::barf2); // ERROR
}

В качестве примечания, у меня это нормально работает с использованием виртуальной функции, что является очевидным подходом, а не указателем на функцию, но я просто пытаюсь заставить его работать таким образом, прежде чем пытаться использовать трюк boost :: bind позже ...

Ответы [ 3 ]

1 голос
/ 10 января 2012

Кроме того, поскольку мои знания о c ++ 11 && bost && stl не самые лучшие, я могу только посоветовать это:

 template <typename T>
    void test(void (T::*f)(int))
  {
    CALL_MEMBER_FN(static_cast<T&>(*this),f)(123);
  }

Все остальные коды совпадают с вашими.

Плохой кастинг, но он скрыт

1 голос
/ 10 января 2012

Можете ли вы обобщить указатель на функцию немного больше?Я имею в виду что-то вроде этого:

typedef void (Foo::*FFunc)(int i);

to:

typedef void (*FFunc)(int i);

Тогда вы можете использовать bind:

b.test(bind(&Bar::barf2, &b));
1 голос
/ 10 января 2012

b.test( ( Foo::FFunc )&Bar::barf2 );

Извините, я не хотел представлять это как ответ, хотел прокомментировать. Пример кода .

РЕДАКТИРОВАТЬ: Ну, может быть, это более "приятный" кастинг, так как это стиль C ++? Обновленный образец.

b.test( static_cast< Foo::FFunc >(&Bar::barf2) );

...