YiFei
YiFei

Reputation: 1856

How to wrap a function with single argument to accept multiple arguments?

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.

Upvotes: 1

Views: 534

Answers (4)

TerraPass
TerraPass

Reputation: 1602

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

Upvotes: 4

gbehar
gbehar

Reputation: 1299

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);};

Upvotes: 0

Rakete1111
Rakete1111

Reputation: 49028

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

Upvotes: 4

Hiura
Hiura

Reputation: 3530

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. ;-)

Upvotes: 4

Related Questions