1

I want some code that will enables me to do:

// Dummy function foo
double foo(double a){return a+1;}
// Some wrapping here ... which generates (maybe a pointer to)
double Foo(double a, ...){return a+1;}
// i.e. ignore any other arguments, just accept

It's mainly because I have a struct member that will store a pointer to function, say double (*)(double, double) normally, but some case it has to store a pointer to a unary function (and I don't really want to use boost.variant).

EDIT: Sorry if I didn't say it clearly, but it should (somehow like a converter) that works for infinite unary functions of a same kind.

YiFei
  • 1,752
  • 1
  • 18
  • 33

4 Answers4

4

Since you're in a specific situation where you need a double x double -> double function, you can wrap foo as follows:

double foo_w(double a, double) { return foo(a); }

If you are interested in a more general solution, you can look into variadic template for the number of arguments (and their respective type) as Mohammadreza Panahi shows in his answer. But try not to over engineer your problem. ;-)

Hiura
  • 3,500
  • 2
  • 20
  • 39
4

Here are two general solutions.

Compile time

This can be accomplished using variadic templates:

double func(double x)
{
    return x + 1;
}

template<typename... Ts>
double wrappedFunc(double x, const Ts&...)
{
    return f(x);
}

wrappedFunc() can be invoked with any number of arguments of any types, only the first one will actually be used and passed to f():

wrappedFunc(5.0, "Hello!", false, -23);    // returns 6.0

Run time

As far as I understand the edit you made, you are looking for a way to do this at run time. Here's one way to do so in C++14, using a function template, returning a lambda with variable number of parameters, which calls the original function, passing its first parameter and ignoring the rest:

template<typename Func>
auto getVariadicWrapper(Func func)
{   
    return [func](auto argument, auto...) {return func(argument);};
}

This function template can be used to construct a wrapper function in the following manner:

// Assuming func() is the same as before

// Create a wrapper function, which passes its first param to func and ignores the rest.
auto wrappedFunc = getVariadicWrapper(func);

// Use it
wrappedFunc(5.0, false, "bananas", 72233);    // returns 6.0
TerraPass
  • 1,562
  • 11
  • 21
  • Does it finally return a pointer or just the function itself? – YiFei Jun 16 '16 at 00:37
  • @YiFei It returns a lambda, which has its own unique type and is not a pointer to function. Since it's a capturing lambda, you can't convert it to a function pointer, to the best of my knowledge (see [this answer](http://stackoverflow.com/a/28746827/1051764)). – TerraPass Jun 16 '16 at 10:13
4

Instead of a function pointer, if you use C++11, you can use std::function to store the functions:

double foo(double, double) {}
double Foo(double, ...) {} //You could also use a template for this one

//Note that the number of parameters of 'func' should be the maximum possible
//arguments of the functions you want to store (here: 1 vs 2)
std::function<double(double, double)> func;

func = foo; //Ok
func = Foo; //Ok

//Now you can call 'func'
func(1, 2); //if 'func' == 'Foo', ignores the 2
Rakete1111
  • 47,013
  • 16
  • 123
  • 162
  • @YiFei of course, because if it would, and you call `func(1, 2)`, what would it do? It can't call `foo` with 2 arguments. That's why you can use the ellipsis `...` to "fake" multiple arguments, and then `func(1, 2)` is well formed – Rakete1111 Jun 15 '16 at 15:53
  • It seems you've misunderstood what I want, but yours seems to work if using `std::function`, i.e. the number of parameters should be the least, as I can always have `...` to do this trick. – YiFei Jun 15 '16 at 16:01
0

Another nice and easy way is with a lambda

If you have

double func (double a)
{
    return a;
}

struct st
{
    double(*foo)(double,double);
};

You can do

st a;
a.foo = [](double a,double b){return func(a);};
gbehar
  • 1,229
  • 10
  • 10
  • Seemed I can't initialize it in struct constructor, must I assign it outside of the struct? – YiFei Jun 16 '16 at 00:26
  • I didn't have trouble doing it in the constructor. Maybe give a code example? (Lambdas are only available since C++11 btw) – gbehar Jun 16 '16 at 06:11