2

I referred to this somewhat similar question. However here the scenario is different:

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
}

In the above test code, I have an overloaded foo inside A. Had there been only 1 foo then the code works fine. But for overloading case, compiler complains as:

error: no matching function for call to `ReceiveFuncPtr(A&, [unresolved overloaded function type])'

Instead of explicit typecasting while calling ReceiveFuncPtr(), is there any way that we can make some changes in its template parameter and enable it to receive foo(int) version always for any similar class A ?

Edit: Idea is not to worry about the type while calling the function. It should be as simple as, ReceiveFuncPtr(obj, &A::foo); And let the template do its work.

Community
  • 1
  • 1
iammilind
  • 68,093
  • 33
  • 169
  • 336

2 Answers2

4

You can write the function template as:

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

This function template will automatically choose void foo (int i).


My previous answer (not deleting it, as it maybe helpful for others):

Your problem:

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

You can do this:

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

pFun is a pointer to void A::f(int)


You can also use typedef as:

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

FunInt pFun  = &A::foo;    // No casting here!
ReceiveFuncPtr(obj, pFun); // No casting here!
Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • I would prefer typecasting rather than that version :). Idea is to not worrying about `A::foo` type while writing code. The template should deduce it As I suggested in the question, `any way that we can make some changes in its template parameter` – iammilind Jun 17 '11 at 05:07
  • @iammilind: See my last solution. :-) – Nawaz Jun 17 '11 at 05:12
  • +1, that's correct. Actually I tried that but I forgot to remove the 2nd template argument `FuncPtr` which was causing error. – iammilind Jun 17 '11 at 05:17
  • I recommend to not do this, because it breaks if you pass a derived class object as first and a pointer to a base class function as second argument. – Johannes Schaub - litb Jun 17 '11 at 14:58
4

how about this:

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