Как передать указатель функции-члена на перегруженный метод в функции-шаблоне?

Я ссылался на этот несколько похожий вопрос. Однако здесь сценарий другой:

struct A
{
  void foo (int i) {} // choice
  void foo (double i) {}
};

template<typename ObjType, typename FuncPtr>
void ReceiveFuncPtr (ObjType o, FuncPtr pf)
{
 (o.*pf)(1);
}

int main ()
{
  A obj;
  ReceiveFuncPtr(obj, &A::foo); // don't want typecast here
}

В приведенном выше тестовом коде у меня есть перегруженный foo внутри A. Если бы было только 1 foo, код работал бы нормально. Но в случае перегрузки компилятор жалуется как:

ошибка: нет соответствующей функции для вызова `ReceiveFuncPtr(A&, [неразрешенный тип перегруженной функции])'

Вместо явного приведения типов при вызове ReceiveFuncPtr() есть ли способ внести некоторые изменения в его параметр template и позволить ему всегда получать версию foo(int) для любого подобного class A ?

Изменить. Идея состоит в том, чтобы не беспокоиться о типе при вызове функции. Это должно быть так просто, как ReceiveFuncPtr(obj, &A::foo); И пусть template делает свою работу.


person iammilind    schedule 17.06.2011    source источник
comment
Определите, что означает любой подобный класс A, тогда вам будет лучше помочь.   -  person Johannes Schaub - litb    schedule 17.06.2011


Ответы (2)


как насчет этого:

template<typename ObjType>
void ReceiveFuncPtr (ObjType o, void (ObjType::*pf)(int))
{
 (o.*pf)(1);
}
person tangxinfa    schedule 17.06.2011

Вы можете написать шаблон функции как:

template<typename ObjType>
void ReceiveFuncPtr (ObjType o, void (ObjType::*pf)(int) )
{
   (o.*pf)(1);
}

Этот шаблон функции автоматически выберет void foo (int i).


Мой предыдущий ответ (не удаляя его, так как он может быть полезен другим):

Твоя проблема:

ReceiveFuncPtr(obj, &A::foo); // don't want typecast here

Ты можешь это сделать:

void (A::*pFun)(int) = &A::foo; // No casting here!
ReceiveFuncPtr(obj, pFun);      // No casting here!

pFun является указателем на void A::f(int)


Вы также можете использовать typedef как:

typedef void (A::*FunDouble)(double);
typedef void (A::*FunInt)(int);

FunInt pFun  = &A::foo;    // No casting here!
ReceiveFuncPtr(obj, pFun); // No casting here!
person Nawaz    schedule 17.06.2011
comment
Я бы предпочел приведение типов, а не эту версию :). Идея состоит в том, чтобы не беспокоиться о типе A::foo при написании кода. Шаблон должен вывести это. Как я предложил в вопросе, any way that we can make some changes in its template parameter - person iammilind; 17.06.2011
comment
@iammilind: см. мое последнее решение. :-) - person Nawaz; 17.06.2011
comment
+1, это правильно. На самом деле я пробовал это, но забыл удалить второй аргумент шаблона FuncPtr, который вызывал ошибку. - person iammilind; 17.06.2011
comment
Я рекомендую не делать этого, потому что это сломается, если вы передадите объект производного класса в качестве первого и указатель на функцию базового класса в качестве второго аргумента. - person Johannes Schaub - litb; 17.06.2011