Creating a function (of fewer parameters) from another function - c++

I would like to do the following. Say I have this:
void f(const char* c) {
// Do stuff with c
}
void g(const char* c, int x, int y) {
// Do other stuff
}
What I'd like to do is to create a function from g that takes a const char* c. That is:
int a = 5;
int b = 9;
expression(g, a, b)("Hi!");
Preferably, expression(g) can be stored in a variable as well. I'm not sure how to declare this variable either.
I have tried using boost::bind; however boost::bind returns a boost::function, and I would like a normal C++ function pointer. Additionally, I also saw this thread:
demote boost::function to a plain function pointer
And neither of the top two solution will work. My function f is constrained to take one parameter (no void* user_data pointer). The reason I need this is that I have a third function, h, that takes in a function of one argument, namely a const char* and does things with it. I'd like to be able to pass in a form of g to h.
h(f) // Valid
h(expression(g, a, b)) // Would like for this to be valid, too
I'm not sure if this is possible, but if it is, do tell :).

Use bind:
#include <functional>
auto h = std::bind(g, std::placeholders::_1, 5, 9);
h("hi");
bind makes copies of the arguments, so beware if you're planning on taking arguments by reference (in which case you may want std::ref). Try to keep the result type auto to avoid unnecessary conversions.
To get a normal C++ function:
void h(char const * s) { g(s, 5, 9); }
Or:
void (*ph)(char const *) = [](const char * s) { g(s, 5, 9); };
Or for the insane:
struct Foo { static void bar(char const * s) { g(s, 5, 9); } };
void (*qh)(char const *) = &Foo::bar;
Usage:
h("hi");
ph("hi");
Foo::bar("hi");
qh("hi");

Related

Taking the address of boost::hana::partial::operator()

Suppose I have a lambda that does something:
auto thing = [](int x){ /* Stuff */ };
I want to save off the value "x" and call it later so I do:
auto other = boost::hana::partial(thing, 42);
Now, because I want to do some type erasure on this I want to take the address of the operator().....so I try to do this:
using type = decltype(other);
void (type::*ptr)(void) = &type::operator();
Clang complains, that the other object does not a sufficient function that matches the requirements: godbolt
It appears that the partial type is returning a reference (to void?)......why does this not work?
It (the operator()) has & const& && etc overloads; your member function pointer does not qualify *this by const or r/l value-ness. So does not match.
Add & or const& or && or const&& before = on the line that fails to compile, and it will compile.
Here is a [MCVE]:
struct foo {
void bar()&{}
};
int main(){
auto p = &foo::bar;
void(foo::*p2)() = p; // lacks &
}

Is it possible to "trick" a function take one argument when it is expecting multiple in C++?

I am looking at the "dlib"-library, more specifically the "find_min" function which is used for "optimization" (http://dlib.net/optimization_ex.cpp.html). The "find_min" function let you pass your own function as an argument, but your own function needs to take only one argument. However the function I need to pass has too many arguments (7 actually), but I need them.
So my question is this:
Is there a way to "compress" my arguments so it seems like only one, or maybe a way to change a function so it only takes one argument, but still gets all the arguments that is needed in some other smart way?
Say you've got this function:
int seven_args(int a, char b, double c, int d, int e, int f, int g) {
...
}
Stuff all the arguments into a struct and make a wrapper function that takes a single struct argument:
struct seven_args_arguments {
int a;
char b;
double c;
int d;
int e;
int f;
int g;
}
int wrapper(seven_args_arguments args) {
return seven_args(args.a, args.b, args.c, args.d, args.e, args.f, args.g);
}
You can define a structure that that contains all your arguments and make the function take a pointer to that structure as its sole argument.
Example:
Struct MyStruct {int param1; double param2; char param3;}
void MyFunction(const MyStruct* p) {......}
To invoke the function:
MyStruct params { 1, 2.5, 'c'};
MyFunction(&params);
Notice if all your parameters are of the same type, you could even better use a vector without the need to define a structure.

Is it possible to pass a function as a parameter in C++?

Is there any way to pass a function as a parameter in C++, like the way that functions can be passed as parameters in C? I know that it's possible to pass a function as a parameter in C using function pointers, and I want to know whether the same is possible in C++.
You can do it like in C. But you can also do it the C++ way (C++11, to be exact):
// This function takes a function as an argument, which has no
// arguments and returns void.
void foo(std::function<void()> func)
{
// Call the function.
func();
}
You can pass a normal function to foo()
void myFunc();
// ...
foo(myFunc);
but you can also pass a lambda expression. For example:
foo([](){ /* code here */ });
You can also pass a function object (an object that overloads the () operator.) In general, you can pass anything that can be called with the () operator.
If you instead use the C way, then the only thing you can pass are normal function pointers.
It's possible in C++ just as in C to pass functions as parameters but with a few differences: we can use function references instead of pointers, templates types in addition to variadic template arguments. For example:
Function references:
In C, we don't have the ability to pass objects by reference. This however is possible in C++:
void f( void (&)() ) {}
f( h );
The difference between references are pointers is subtle, but important. For instance, we can't pass NULL or 0 to a function expecting a reference; the argument must be satisfied with its type immediately. References are usually preferred in most cases over pointers.
Templates:
Templates allow us to generically pass functions with variable type attributes as parameters:
template <class T, class U>
void f( T (&)( U ) ) {}
The above signature accepts a function with any return type or parameter list (the only setback is that the function must take one argument).
In addition to this feature, we can also utilize varaidic templates to allow functions with variable-length parameter lists:
template <class T, class ...U>
void f( T (&)( U... ) ) {}
int h(int, int) { .. }
bool g(std::string) { .. }
f( h );
f( g );
The implementation of f can also use perfect forwarding if we are using U&&:
template <class T, class ...U>
void f( T (&fun)( U&&...) ) {
// ...
fun( std::forward<U>(u)... );
}
There are also lambdas which are commonly bound with std::function<T(U)>.
Yes, function pointers work exactly the same way in C++ as in C.
Yes, like this:
#include <stdio.h>
typedef void (*my_func)(int);
void do_something (my_func f)
{
f (10);
}
void square (int j)
{
printf ("squared: %d\n", j * j);
}
void cube (int j)
{
printf ("cubed: %d\n", j * j * j);
}
int main (int argc, char *argv[])
{
do_something (square);
do_something (cube);
}
The output is:
squared: 100
cubed: 1000
The typedef is to make the syntax for do_something() a bit more readable.
I would like to point out that, since you are using C++ already, it is much easier ways to achieve the same with virtual functions.
Yes, it is possible.
I found a working example program (which can be tested and edited online, and illustrates the concept well): http://ideone.com/6kSTrp#view_edit_box
//this was taken from http://www.cprogramming.com/tutorial/function-pointers.html
#include <stdio.h>
void my_int_func(int x)
{
printf( "%d\n", x );
}
int main()
{
void (*foo)(int); //pointer to an int function
foo = &my_int_func;
/* call my_int_func (note that you do not need to write (*foo)(2) ) */
foo( 2 );
/* but if you want to, you may */
(*foo)( 2 );
return 0;
}

how to avoid static member function when using gsl with c++

I would like to use GSL within a c++ class without declaring member functions as static. The reason for this is because I don't know them too well and I'm not sure about thread safety. From what I read, std::function might be a solution but I'm not sure how to use it.
My question comes down to how can I remove static in declaration of g?
#include<iostream>
#include <functional>
#include <stdlib.h>
#include <gsl/gsl_math.h>
#include <gsl/gsl_monte.h>
#include <gsl/gsl_monte_plain.h>
#include <gsl/gsl_monte_miser.h>
#include <gsl/gsl_monte_vegas.h>
using namespace std;
class A {
public:
static double g (double *k, size_t dim, void *params)
{
double A = 1.0 / (M_PI * M_PI * M_PI);
return A / (1.0 - cos (k[0]) * cos (k[1]) * cos (k[2]));
}
double result() {
double res, err;
double xl[3] = { 0, 0, 0 };
double xu[3] = { M_PI, M_PI, M_PI };
const gsl_rng_type *T;
gsl_rng *r;
////// the following 3 lines didn't work ///////
//function<double(A,double*, size_t, void*)> fg;
//fg = &A::g;
//gsl_monte_function G = { &fg, 3, 0 };
gsl_monte_function G = { &g, 3, 0 };
size_t calls = 500000;
gsl_rng_env_setup ();
T = gsl_rng_default;
r = gsl_rng_alloc (T);
{
gsl_monte_plain_state *s = gsl_monte_plain_alloc (3);
gsl_monte_plain_integrate (&G, xl, xu, 3, calls, r, s, &res, &err);
gsl_monte_plain_free (s);
}
gsl_rng_free (r);
return res;
}
};
main() {
A a;
cout <<"gsl mc result is " << a.result() <<"\n";
}
Update (1):
I tried changing gsl_monte_function G = { &g, 3, 0 }; to gsl_monte_function G = { bind(&A::g, this,_1,_2,_3), 3, 0 }; but it didn't work
Update (2):
I tried using assigning std::function to a member function but it didn't work either.
Update (3)
in the end I wrote a non-member function:
double gmf (double *k, size_t dim, void *params) {
auto *mf = static_cast<A*>(params);
return abs(mf->g(k,dim,params));
//return 1.0;
};
It worked but it's a messy solution because I needed to write a helper function. With lambdas,function and bind, there should be a way to have everything logical within the class.
You can easily wrap member functions using the following code (which is a well known solution)
class gsl_function_pp : public gsl_function
{
public:
gsl_function_pp(std::function<double(double)> const& func) : _func(func){
function=&gsl_function_pp::invoke;
params=this;
}
private:
std::function<double(double)> _func;
static double invoke(double x, void *params) {
return static_cast<gsl_function_pp*>(params)->_func(x);
}
};
Then you can use std::bind to wrap the member function in a std::function. Example:
gsl_function_pp Fp( std::bind(&Class::member_function, &(*this), std::placeholders::_1) );
gsl_function *F = static_cast<gsl_function*>(&Fp);
However, you should be aware about the performance penalties of std::function before wrapping member functions inside gsl integration routine. See template vs std::function . To avoid this performance hit (which may or may not be critical for you), you should use templates as shown below
template< typename F >
class gsl_function_pp : public gsl_function {
public:
gsl_function_pp(const F& func) : _func(func) {
function = &gsl_function_pp::invoke;
params=this;
}
private:
const F& _func;
static double invoke(double x, void *params) {
return static_cast<gsl_function_pp*>(params)->_func(x);
}
};
In this case, to call a member function you need the following
Class* ptr2 = this;
auto ptr = [=](double x)->double{return ptr2->foo(x);};
gsl_function_pp<decltype(ptr)> Fp(ptr);
gsl_function *F = static_cast<gsl_function*>(&Fp);
PS: the link template vs std::function explains that compiler usually has an easier time optimizing templates than std::function (which is critical for performance if your code is doing heavy numerical calculation). So even tough the workaround in the second example seems more cumbersome, I would prefer templates than std::function.
GSL takes a C-type functions “int (*)(char,float)” rather than C++-type “int (Fred::*)(char,float)”. To convert a member function to the C-type function, you need to add static.
see Is the type of “pointer-to-member-function” different from “pointer-to-function”?
Why are you worried about the static function in this case?
Variables and/or objects declared in a static function are not shared between different threads unless they are static themselves (which in your case they are not).
Is your code failing to do something?
Sorry, but what you're trying to do doesn't make any sense. Whatever thread safety issues you're worried about, they won't be solved by adding or removing the static keyword.
The only reason why you would make g non-static would be if an instance of A was somehow required for g's operation. And g's current implementation doesn't require such an instance.
Note you can also make g a global function, without the static keyword. There would be no visible difference in your case. However it's better style in your case to have g in the class which makes use of it, as a static function.
Also, Here is some related material about pointers to (static/non-static) member functions.

C++ typedef declaration

Can you please explain what does the following line means?
typedef int (*Callback)(void * const param,int s)
It means that Callback is a new name for the type : pointer to a function returning an int and taking two parameters of type 'const pointer to void' and 'int'.
Given a function f :
int f(void * const param, int s)
{
/* ... */
}
The Callback can be used to store a pointer to f :
Callback c = &f;
The function f can be later invoked through the pointer without directly referring to its name :
int result = c(NULL, 0);
At the point of the call, the name f does not appear.
It creates a new "alias" or name by which you can refer to pointers to functions that return int and take two parameters: a void* const and an int. You can then create variables of that type, assign to them, invoke the function through them etc as in:
int fn(void * const param,int s) { ... }
Callback p;
p = fn;
int x = p(NULL, 38);
Note that typedefs do not really create new types... every equivalent typedef is resolved to the single real type for the purposes of overload resolution, template instantiation etc..
It declares a function type:
// Set up Callback as a type that represents a function pointer
typedef int (*Callback)(void * const param,int s);
// A function that matches the Callback type
int myFunction(void* const param,int s)
{
// STUFF
return 1;
}
int main()
{
// declare a variable and assign to it.
Callback funcPtr = &myFunction;
}