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.
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;
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.
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.
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.
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.
C++ overloaded function pointer ambiguity
Once you fix the typos, the main problem is that you're trying to cast a member function pointer to a function pointer.
That is, the following is illegal:
static_cast<uint32_t(*)(double)>(&Sample::method)
error: invalid static_cast from type
‘uint32_t (Sample::*)(double) {aka unsigned int (Sample::*)(double)}’
to type
‘uint32_t (*)(double) {aka unsigned int (*)(double)}’
The syntax for a member function pointer is
ReturnT(ClassT::*)(ArgTs);
So your cast would have to be:
static_cast<uint32_t(Sample::*)(double)>(&Sample::method)
Example:
#include <iostream>
#include <functional>
struct Sample
{
uint32_t method(char* input1, double input2) { return 0; }
uint32_t method(double input1) { return 0; }
};
template<class T, class... Args>
void processInput(T &&t, Args&&... a)
{
auto task = std::bind(t, a...);
(void)task;
}
int main()
{
Sample* obj = new Sample();
processInput(static_cast<uint32_t(Sample::*)(double)>(&Sample::method), obj, 2.0f);
return 0;
}
Bad type deduction when passing overloaded function pointer and its arguments
Theory
For each function template Invoke
, the template argument deduction (that must succeed for overload resolution to consider it) considers each Foo
to see whether it can deduce however many template parameters (here, two) for the one function parameter (func
) involved. The overall deduction can succeed only if exactly one Foo
matches (because otherwise there is no way to deduce S
). (This was more or less stated in the comments.)
The first (“by value”) Invoke
never survives: it can deduce from any of the Foo
s. Similarly, the second (“non-const
reference”) overload accepts the first two Foo
s. Note that these apply regardless of the other argument to Invoke
(for arg
)!
The third (const T&
) overload selects the corresponding Foo
overload and deduces T
=int
; the last does the same thing with the last overload (where T&&
is a normal rvalue reference), and therefore rejects lvalue arguments despite its universal reference (which deduces T
as int&
(or const int&
) in that case and conflicts with func
’s deduction).
Compilers
If the argument for arg
is an rvalue (and, as usual, isn’t const), both plausible Invoke
overloads succeed at deduction, and the T&&
overload should win (because it binds an rvalue reference to an rvalue).
For the case from the comments:
template <typename U>
void Bar (U &&);
int main() {
int num;
Invoke<void>(&Bar, num);
}
No deduction takes place from &Bar
since a function template is involved, so T
is successfully deduced (as int
) in every case. Then, deduction happens again for each case to identify the Bar
specialization (if any) to use, deducing U
as fail, int&
, const int&
, and int&
respectively. The int&
cases are identical and plainly better, so the call is ambiguous.
So Clang is right here. (But there’s no “undefined behavior” here.)
Solution
I don’t have a general answer for you; since certain parameter types can accept multiple value-category/const-qualification pairs, it’s not going to be easy to emulate overload resolution correctly in all such cases. There have been proposals to reify overload sets in one way or another; you might consider one of the current techniques along those lines (like a generic lambda per target function name).
C++ address of overloaded function
The easiest solution is to store the pointer to the overloaded function in a pointer, first:
#include <cstdio>
static void test0(void)
{
printf("%s [%d]\n", __func__, __LINE__);
}
static void test0(int a)
{
printf("%s [%d] %d\n", __func__, __LINE__, a);
}
int main(void) {
void (*select1)(void) = test0; // will match void(void)
void (*select2)(int) = test0; // will match void(int)
select1();
select2(42);
return 0;
}
$ ./a.out
test0 [5]
test0 [10] 42
If you want to call the stored void*
, then you have to make it a function pointer again. You can do that by e.g. reinterpret_cast<void(*)(int)>(p)
.
C++ passing overloaded operator() of class as function pointer
Supposing that you have to use a function pointer, and that your functor has no state, you can use a lambda as glue:
void takesFunctionPointer(void (*)());
struct MyFunctor {
void operator()();
};
// ...
takesFunctionPointer([] { return MyFunctor{}(); });
Related Topics
What Data Structure, Exactly, Are Deques in C++
How Does Q_Foreach (= Foreach) MACro Work and Why Is It That Complex
Opening a Window That Has No Title Bar with Win32
How to Use C Source Files in a C++ Project
What's the Difference Between New Char[10] and New Char(10)
Opencv - Dll Missing, But It's Not
Search 25 000 Words Within a Text
Is Using Increment (Operator++) on Floats Bad Style
Should Accessors Return Values or Constant References
Using Pair as Key in a Map (C++/Stl)
How to Build Libcxx and Libcxxabi by Clang on Centos 7
Qapplication in Non-Main Thread
What Is the Use of "Delete This"
Double to String Without Scientific Notation or Trailing Zeros, Efficiently
Print Out the Values of a (Mat) Matrix in Opencv C++
Why Can't You Do Bitwise Operations on Pointer in C, and Is There a Way Around This