How to Specify a Pointer to an Overloaded Function

How do I specify a pointer to an overloaded function?

You can use static_cast<>() to specify which f to use according to the function signature implied by the function pointer type:

// Uses the void f(char c); overload
std::for_each(s.begin(), s.end(), static_cast<void (*)(char)>(&f));
// Uses the void f(int i); overload
std::for_each(s.begin(), s.end(), static_cast<void (*)(int)>(&f));

Or, you can also do this:

// The compiler will figure out which f to use according to
// the function pointer declaration.
void (*fpc)(char) = &f;
std::for_each(s.begin(), s.end(), fpc); // Uses the void f(char c); overload
void (*fpi)(int) = &f;
std::for_each(s.begin(), s.end(), fpi); // Uses the void f(int i); overload

If f is a member function, then you need to use mem_fun, or for your case, use the solution presented in this Dr. Dobb's article.

Pass a function pointer of an overloaded member function?

Member function pointer and non-member function pointer are not the same thing. The type for member function pointer in your code is not correct, change it to

myObject = new Object(static_cast<void(myclass::*)()>(&myclass::repaint);
~~~~~~~~~

BTW: The void in parameter list is redundant.

Overload a pointer to an overloaded function

Why are you doing this? Function pointers are for runtime polymorphism based on application state. Plain old overloads work fine if, the only variance is the argument type.

If you want to be able to, say write a library that will call overloads defined later, in client code, do something like the following:

void foo(int x) { printf("int\n");}
void foo(const char* c){ printf("char*\n"); }

template <class T> void callfoo(T t) { foo(t); }

int main(int argc, char* argv[])
{
int x = 3;
callfoo(x);

const char* p = "Hello world";
callfoo(p);

return 0;
}

This allows the lib to call overloads for types it is not actually aware of until link time.

Disambiguate overloaded member function pointer being passed as template parameter

The issue is here:

l.call(&foo::func, "hello");
l.call(&foo::func, 0.5);

For both lines, the compiler doesn't know which foo::func you are referring to. Hence, you have to disambiguate yourself by providing the type information that is missing (i.e., the type of foo:func) through casts:

l.call(static_cast<void (foo::*)(const std::string&)>(&foo::func), "hello");
l.call(static_cast<void (foo::*)(const double )>(&foo::func), 0.5);

Alternatively, you can provide the template arguments that the compiler cannot deduce and that define the type of func:

l.call<void, const std::string&>(&foo::func, "hello");
l.call<void, double >(&foo::func, 0.5);

Notice that you have to use double and not const double above. The reason is that generally double and const double are two different types. However, there's one situation where double and const double are considered as if they were the same type: as function arguments. For instance,

void bar(const double);
void bar(double);

are not two different overloads but are actually the same function.

C++ overloaded method pointer

(void (A::*)()) &A::f
(void (A::*)(int)) &A::f

function pointers and member function pointers have this feature - the overload can be resolved by to what the result was assigned or cast.

If the functions are static, then you should treat them as ordinary functions:

(void (*)()) &A::f;
(void (*)(int)) &A::f;

or even

(void (*)()) A::f;
(void (*)(int)) A::f;

Get pointer to overloaded function that would be called

There is no way to get the function of an overload-set which would be called with the given arguments, unless you already know its signature.

And if you know, what's the point?

The problem is that for any given arguments, taking into account implicit conversions, references, cv-qualifiers, noexcept, old-style vararg, default arguments, and maybe also literal 0 being a null pointer constant, there are an infinite number of function-signatures which would match. And there is currently no facility for "just" listing all candidates.

How to pass an overloaded function pointer as an argument without resolving (C++03)

You can create a function object wrapping your function template (or replacing it):

struct add_printer {
template<typename T>
void operator()(T a, T b) const {
add_print(a, b);
}
};

And then use it like this:

ApplyToFields(&ns1, &ns2, add_printer());

This will delay overload resolution until add_printer's operator() is actually instantiated when it is used in ApplyToFields.

In C++14, you could use a polymorphic lambda:
[](auto a, auto b) { add_print(a, b); }
which, unlike the function object, can be defined almost anywhere, not just at namespace scope.

How to pass an overloaded member-function as parameter?

You need to cast to member-function pointer, not to std::function:

otherFunction ( static_cast<void(Bar::*)(const Foo&)>(&Bar::function) );

Live

[EDIT]

Explanation:

otherFunction ( &Bar::function );

otherFunction takes std::function as a parameter. std::function has an implicit constructor (an implicit conversion) from a function pointer (a member function or a free function, and other "callable" types, doesn't matter here). It looks like this:

template< class F > 
function( F f );
  • it's a template parameter
  • while F is "callable", it doesn't specify the signature of F

This means that compiler doesn't know which Bar::function you meant, because this constructor doesn't put any restrictions on input parameter. That's what compiler is complaining about.

You tried

static_cast< std::function<void ( Bar& , const Foo& )> > ( &Bar::function );

While it looks like compiler has all details it needs here (the signature), actually the same constructor is called, so nothing effectively changed.
(Actually, the signature is incorrect, but even correct one wouldn't work)

By casting to a function pointer we provide its signature

static_cast<void(Bar::*)(const Foo&)>(&Bar::function)

So ambiguity is resolved as there's only one such function so compiler is happy.



Related Topics



Leave a reply



Submit