C++ pass a function as argument - c++

I need to call a library function in C++, it has the form:
double brents_fun(std::function <double(double)> f);
I can call this function by the following:
double fun1(double x)
{
return -2.0*x+1;
}
void main()
{
brents_fun(fun1);
return 0;
}
I want to pass another function to brents_fun, like:
double fun2(double x, double y)
{
return -2.0*x+y;
}
void main()
{
y=12.0;
brents_fun( fun2(x,y=12) );
return 0;
}
In my real code, y is complicated. I need to read data from file, do some calculations with the data to generate y. That's why I need two argument x and y in fun2. y will not be changed during calling brents_fun.
Since y is not changed, is there a way to pass fun2 to brents_fun?
Thank you.
Hao

You basically want to partially apply a function to pass it as an argument to brents_fun, this is possible and you have two ways to do it in C++11:
with a lambda
with std::bind
Both solutions:
double brents_fun(std::function <double(double)> f)
{
return f(0.0);
}
double fun1(double x, double y)
{
return x+y;
}
int main() {
double res1 = brents_fun([](double x) { return fun1(x, 12.0); });
double res2 = brents_fun(std::bind(fun1, placeholders::_1, 12.0));
}
While the lambda one is more suitable to optimizations in general both solutions are equivalent. std::bind can be polymorphic while a lambda can't, but that's not the point in your situation. I'd say just stick to the syntax you prefer.

brents_fun accepts as argument a function in the form of: double someFunction(double), as you might already know. No functions of other return types, nor arguments, can be used. In this particular case, you can pass the fun1 function, them sum y when you have it calculated. Also, to post formatted code, simply select it and ctrl+k.

Related

std::bind won't accept an std::cref of a bind-placeholder - why?

I try to pass a method as a parameter function, which itself takes a parameter, by using std::cref, but somehow I cannot get it right. What is wrong?
struct node
{
void get(int &i){
i = x;
}
int x, z;
void foo(std::function<void(int&)>t){
t(z);
}
void bar(){
x = 7;
z = 10;
foo(std::bind(&node::get, this, std::cref(_1)));
cout<< "z:" << z << std::endl; //Here is expected that z is changed to 7
}
};
std::bind can only process placeholders directly as parameters: std::bind(…, _1, …).
std::cref(_1) wraps the placeholder in a std::reference_wrapper. bind doesn't recognize it as a placeholder anymore, and tries to pass it directly to the bound function, as it would do with any other non-placeholder parameter.
To work around this and other limitations of bind, use a lambda:
foo([this](int &x){return get(std::ref(x));});
I've replaced cref with ref here, because get() expects a non-const reference. You can't use cref here, with or without the lambda. (Note that std::ref(x) is equivalent to x here, and is used instead of x for demonstration purposes only.)

Using the same double in different functions

I have two functions which use the same doubles ie like
in the .h I declare
class MyClass : {
public :
double arg1, arg2;
void getVarA(double a, double b);
void getVarB(double a, double b);
void Reset();
}
and in my .C I have something like
void MyClass::Reset(){
arg1 = 0.0f;
arg2 = 0.0f;
}
void MyClass::getVarA(double a, double b){
arg1+=2*a;
arg2+=2*b;
return arg1-arg2;
}
void MyClass::getVarB(double a, double b){
arg1+=2+a;
arg2+=2+b;
return arg1-arg2;
}
The problem is that in principle I want to create a copy of arg1,arg2 each one taking values in each function (ie in each function to be possible to take different values) so that arg1,arg2 dont "speak" between the two different functions and whenever I change the arg1 in getVarA function not to commute with the arg1 in getVarB function.
Sorry, probably my example is poorly phrased but I am just newbie..
thanks
Make your variables arg1, arg2 as function local variables.
void MyClass:getVarA(double a, double b) {
double arg1, arg2;
arg1+=2*a;
arg2+=2*b
return arg1-arg2
}
void MyClass:getVarB(double a, double b) {
double arg1, arg2;
arg1+=2+a;
arg2+=2+b
return arg1-arg2
}
They will become different variables. None of changes made in getVarA arg1, arg2 will affect arg1, arg2 from getVarB
EDIT
According to #harper comment, it is strongly recommended to avoid uninitialized variables. You can't assume initial value of arg1 and arg2 variables. Your should explicit set initial value
double arg1 = 0.0;
double arg2 = 0.0;
"The problem is that in principle I want to create a copy of arg1,arg2"
You can do exactly that:
void MyClass::getVarA(double a, double b)
{
double arg1Copy = arg1;
double arg2Copy = arg2;
arg1Copy+=2*a;
arg2Copy+=2*b;
return arg1Copy-arg2Copy;
}
Now arg1 and arg2 are not modified by your method. In fact you can even declare your method as const to inform the compiler that you do not want the data members to actually be modified by your method.
This answer is based on the following interpretation of your question:
Each of the getVar functions is supposed to remember something about previous calls. The value returned from a function call is supposed to change based on what calls were made to that function in the past. For example, if you ran this code, x1 and x2 would have different values:
MyClass mc;
double x1 = mc.getVarA(1,1);
double x2 = mc.getVarA(1,1);
If you want x1 and x2 to have different values (because the first call is supposed to change what values are used in the second call), then this answer is appropriate. If you want x1 and x2 to have the same value (because you don't want getVarA to remember anything about previous function calls), nnesterov's suggestion to use local variables is a better answer than this one.
You want what is remembered about calls to getVarA to be independent from what is remembered about calls to getVarB.
With that in mind, here's the .h:
class MyClass {
public :
double _varA1, _varA2;
double _varB1, _varB2;
MyClass();
double getVarA(double a, double b);
double getVarB(double a, double b);
void Reset();
};
and here's the .c:
MyClass::MyClass(){
Reset();
}
void MyClass::Reset(){
_varA1 = 0.0;
_varA2 = 0.0;
_varB1 = 0.0;
_varB2 = 0.0;
}
double MyClass::getVarA(double a, double b){
_varA1 += 2*a;
_varA2 += 2*b;
return _varA1 - _varA2;
}
double MyClass::getVarB(double a, double b){
_varB1 += 2+a;
_varB2 += 2+b;
return _varB1 - _varB2;
}
Things to notice:
Each of the two get functions has its own set of instance variables. That way you can change one function's data without changing the other function's data.
The constructor calls Reset() so that the variables are initialized when you first create an instance of the class. That way you can predict what will happen the first time you call each get function.
The return type of the get functions has been changed to double, to match the implementation.

Looping over the parameters of a defined function in C++

I am rather a beginner in C++ and I don't know how to solve the following issue.
I have a working code which find the root of a function using the Brent method. The issue I am interested in is how to loop over different values of the parameters of the function, assuming the same specification.
Here is a simpler example. I call a function which call another defined function AFunction.
#include <stdio.h>
#include <math.h>
double x1,x2,res,r;
// Simple Function
double AFunction(double x) {
return ((x)+2);
}
// A second function that call the first one
double AddF( double x1, double x2, double *res )
{
double result=AFunction(x1)+AFunction(x2);
return (result);
}
int main() {
x1=1.0;
x2=2.0;
r=AFunction(x1,x2,&res);
}
What I am interested in is to loop over the parameter(s) of the defined function, considering the fact that I would like to have the AFunction depending only on x.
That is, consider the function defined below:
// Simple Function
double AFunction(double x) {
return ((x)+a);
}
I want to repeatedly call AFunction for different values of a which can be stored in a vector.
If you mean looping over parameters and calling a function, then you have to pass a parameters in come container, or use a variable length list.
double AddF( std::list<double> const& params) const
{
double result = 0;
for( auto& d : params) result += AFunction( d);
return result;
}

Callback functions with different arguments

I have two functions with a little different functionality, so I can't make them as template functions.
int func64(__int64 a) {
return (int) a/2;
}
int func32(int a) {
return a--;
}
Depending on variable b64, I would like to call func64 or func32. I don't want check if b64 is true many times in my code, so I use pointers to functions.
void do_func(bool b64) {
typedef int (*pfunc32)(int);
typedef int (*pfunc64)(__int64);
pfunc32 call_func;
if (b64)
call_func = func64; //error C2440: '=' : cannot convert from 'int (__cdecl *)(__int64)' to 'pfunc32'
else
call_func = func32;
//...
call_func(6);
}
How can I avoid this error and cast call_func to pfunc32 or pfunc64?
The language requires all functions called through the same function pointer to have the same prototype.
Depending on what you want to achieve, you could use the pointer/cast aproach already mentioned (which satisfies this requirement at the loss of type safety) or pass a union instead:
union u32_64
{
__int64 i64;
int i32;
};
int func64(union u32_64 a) {
return (int) a.i64/2;
}
int func32(union u32_64 a) {
return --a.i32;
}
void do_func(bool b64) {
typedef int (*pfunc)(union u32_64);
pfunc call_func;
if (b64)
call_func = func64;
else
call_func = func32;
//...
union u32_64 u = { .i64 = 6 };
call_func(u);
}
Pass a void pointer and cast it in the function body.
Of course this means less compiler control if you use the wrong type; if you call func64 and pass an int to it the program will compile and produce wrong results without giving you any tip of what is going wrong.
int func64(void *a) {
__int64 b = *((__int64*) a);
return (int) b/2;
}
int func32(void *a) {
int b = *((int *) a)
return b-1;
}
I need to call func32() or func64() depending on flag b64
So do that:
void do_func(bool b64) {
if (b64)
func64(6);
else
func32(6);
}
Well, first of all, please note that function func32 is returning the input argument as is.
This is because with return a--, you are returning the value of a before decrementing it.
Perhaps you meant to return a-1 instead?
In any case, you can simply declare this function as int func32(__int64 a).
This way, it will have the same prototype as function func64, but will work exactly as before.
BTW, calling a function through a pointer might be more "expensive" than a simple branch operation, so depending on your application, you might be better off with a simple if/else conditional statement...
Make a wrapper for func64:
int func64_as_32(int a) {
return func64(a);
}
Now you can assign either func32 or func64_as_32 to call_func since they have the same signature. The value you pass in, 6, has type int so passing it to func64_as_32 has the same effect as passing it directly to func64.
If you have call sites where you pass in a value of type __int64 then you'd do it the other way around, wrap func32.
As bool in C++ converts to int ( true => 1, false => 0 ) you can use b64 as array index. So take SJuan76's advice, convert your functions prototype to int f(void*) and put them into array int (*array_fun[2])(void* x); . You can call these functions then like that :
int p = 6;
array_fun[b64](&p);

C++ same function parameters with different return type

I need to find some way to mock an overload of a function return type in C++.
I know that there isn't a way to do that directly, but I'm hoping there's some out-of-the-box way around it.
We're creating an API for users to work under, and they'll be passing in a data string that retrieves a value based on the string information. Those values are different types. In essence, we would like to let them do:
int = RetrieveValue(dataString1);
double = RetrieveValue(dataString2);
// Obviously, since they don't know the type, they wouldn't use int =.... It would be:
AnotherFunction(RetrieveValue(dataString1)); // param of type int
AnotherFunction(RetrieveValue(dataString2)); // param of type double
But that doesn't work in C++ (obviously).
Right now, we're having it set up so that they call:
int = RetrieveValueInt(dataString1);
double = RetrieveValueDouble(dataString2);
However, we don't want them to need to know what the type of their data string is.
Unfortunately, we're not allowed to use external libraries, so no using Boost.
Are there any ways we can get around this?
Just to clarify, I understand that C++ can't natively do it. But there must be some way to get around it. For example, I thought about doing RetrieveValue(dataString1, GetType(dataString1)). That doesn't really fix anything, because GetType also can only have one return type. But I need something like that.
I understand that this question has been asked before, but in a different sense. I can't use any of the obvious answers. I need something completely out-of-the-box for it to be useful to me, which was not the case with any of the answers in the other question asked.
You've to start with this:
template<typename T>
T RetrieveValue(std::string key)
{
//get value and convert into T and return it
}
To support this function, you've to work a bit more, in order to convert the value into the type T. One easy way to convert value could be this:
template<typename T>
T RetrieveValue(std::string key)
{
//get value
std::string value = get_value(key, etc);
std::stringstream ss(value);
T convertedValue;
if ( ss >> convertedValue ) return convertedValue;
else throw std::runtime_error("conversion failed");
}
Note that you still have to call this function as:
int x = RetrieveValue<int>(key);
You could avoid mentioning int twice, if you could do this instead:
Value RetrieveValue(std::string key)
{
//get value
std::string value = get_value(key, etc);
return { value };
}
where Value is implemented as:
struct Value
{
std::string _value;
template<typename T>
operator T() const //implicitly convert into T
{
std::stringstream ss(_value);
T convertedValue;
if ( ss >> convertedValue ) return convertedValue;
else throw std::runtime_error("conversion failed");
}
}
Then you could write this:
int x = RetrieveValue(key1);
double y = RetrieveValue(key2);
which is which you want, right?
The only sane way to do this is to move the return value to the parameters.
void retrieve_value(std::string s, double& p);
void retrieve_value(std::string s, int& p);
<...>
double x;
retrieve_value(data_string1, x);
int y;
retrieve_value(data_string2, y);
Whether it is an overload or a specialization, you'll need the information to be in the function signature. You could pass the variable in as an unused 2nd argument:
int RetrieveValue(const std::string& s, const int&) {
return atoi(s.c_str());
}
double RetrieveValue(const std::string& s, const double&) {
return atof(s.c_str());
}
int i = RetrieveValue(dataString1, i);
double d = RetrieveValue(dataString2, d);
If you know your value can never be something like zero or negative, just return a struct holding int and double and zero out the one you don't need...
It's a cheap and dirty, but easy way...
struct MyStruct{
int myInt;
double myDouble;
};
MyStruct MyFunction(){
}
If the datastrings are compile-time constants (as said in answering my comment), you could use some template magic to do the job. An even simpler option is to not use strings at all but some data types which allow you then to overload on argument.
struct retrieve_int {} as_int;
struct retrieve_double {} as_double;
int RetrieveValue(retrieve_int) { return 3; }
double RetrieveValue(retrieve_double) { return 7.0; }
auto x = RetrieveValue(as_int); // x is int
auto y = RetrieveValue(as_double); // y is double
Unfortunately there is no way to overload the function return type see this answer
Overloading by return type
int a=itoa(retrieveValue(dataString));
double a=ftoa(retrieveValue(dataString));
both return a string.
As an alternative to the template solution, you can have the function return a reference or a pointer to a class, then create subclasses of that class to contain the different data types that you'd like to return. RetrieveValue would then return a reference to the appropriate subclass.
That would then let the user pass the returned object to other functions without knowing which subclass it belonged to.
The problem in this case would then become one of memory management -- choosing which function allocates the returned object and which function deletes it, and when, in such a way that we avoid memory leaks.
The answer is simple just declare the function returning void* type and in the definition return a reference to the variable of different types. For instance in the header (.h) declare
void* RetrieveValue(string dataString1);
And in the definition (.cpp) just write
void* RetrieveValue(string dataString1)
{
if(dataString1.size()<9)
{
static double value1=(double)dataString1.size();
return &value1;
}
else
{
static string value2=dataString1+"some string";
return &value2;
}
}
Then in the code calling RetrieveValue just cast to the right value
string str;
string str_value;
double dbl_value;
if(is_string)
{
str_value=*static_cast<*string>(RetrieveValue(str));
}
else
{
dbl_value=*static_cast<*double>(RetrieveValue(str));
}
Since you used an example that wasn't really what you wanted, you threw everyone off a bit.
The setup you really have (calling a function with the return value of this function whose return type is unknowable) will not work because function calls are resolved at compile time.
You are then restricted to a runtime solution. I recommend the visitor pattern, and you'll have to change your design substantially to allow for this change. There isn't really another way to do it that I can see.