Reputation: 333
I am trying to use function pointers and lambdas together using one interface. I decided to use std::function
, but I quickly found out that it cannot deal with overloaded functions by itself.
Example:
void foobar(double i_double ){std::cout << "double argument" << i_double << std::endl;}
void foobar(){std::cout << "no argument" << std::endl;}
void foobar(int){std::cout << "int argument" << std::endl;}
std::function<void(double)> func = static_cast<void(*)(double)>(&foobar);
This code only compiles by using a static_cast
. Since at our company we have quite a lot of overloaded functions this is too much of a hassle. For now I decided to implement two interfaces: One for std::function
objects and another one for function pointers, although I would really like to just wrap the function pointers in a std::function
object as well (without additional code on the calling side).
Any "nice" solution to this problem?
edit: The way I will be using it is part of a large framework, but boils down to the code below. I hope the following code below makes the use case clear.
namespace
{
bool IsAllowed(string) {...}
bool IsAllowed(int) {...}
}
CIteratorFilter<String>( listofstrings, IsAllowed );
CSomeObject object;
CIteratorFilter<String>( listofstrings,
[&object](String i_string ) { return object.IsAllowed( i_string ); }
);
Currently this CIteratorFilter needs to implement both the function pointer and std::function
interface, which is not really nice in my opinion.
Upvotes: 1
Views: 59
Reputation: 70030
Use C++11 features with macro-magic.
#define FUNCTION(RETURN, NAME, ...) \
std::function<RETURN (__VA_ARGS__)>(static_cast<RETURN(*)(__VA_ARGS__)>(&NAME))
Usage:
auto func1 = FUNCTION(void, foobar, double);
auto func2 = FUNCTION(void, foobar);
auto func3 = FUNCTION(void, foobar, int);
If you don't want to use variable argument then below is an alternate way of doing it:
#define FUNCTION(RETURN, NAME, PARAMETERS) \
std::function<RETURN PARAMETERS>(static_cast<RETURN(*)PARAMETERS>(&NAME))
Usage:
auto func1 = FUNCTION(void, foobar, (double));
auto func2 = FUNCTION(void, foobar, ());
auto func3 = FUNCTION(void, foobar, (int));
Upvotes: 0
Reputation: 75815
See... an XY problem.
This or anything similar is not needed:
std::function<void(double)> func = static_cast<void(*)(double)>(&foobar);
You need to use templates:
template <class Func>
CIteratorFilter<String>( listofstrings, Func func) {
// call func whatever it may be function pointer, lambda, callable object:
func(..whatever params...);
}
you can use perfect fowarding for func
if you want
Upvotes: 1
Reputation: 409356
Why not use a non-capturing lambda with the correct argument and that calls the foobar
function?
Like
std::function<void(double)> func = [](double d){ foobar(d); };
That's the nicest I can think of.
Upvotes: 0