Looping over the parameters of a defined function in C++ - 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;
}

Related

Not output is coming when below code is executed in C++ for function overloading

Below is the code, when I am executing. No output in the console. Not sure why.
I am testing one example of function overloading in C++.
Function Overloading. Created 2 functions of the same name with different arguments. When tried to pass integer value in main during the function call. It worked fine. But when passed as float number, neither error nor output is coming.
#include <iostream>
using namespace std;
int max(int x,int y)
{
cout<<"Entered in max int"<<endl;
if(x>=y)
return x;
else
return y;
}
float max(float x,float y)
{
cout<<"Entered in max float"<<endl;
if(x>=y)
return x;
else
return y;
}
int main()
{
float x;
x=max(5.9,6.7);
}
First you are not outputting the result of the function and 2nd your function is not being called because you are using using namespace stdso when you call max std::max is being called.
To call your version ofmax you have to access the global scope. Like this ::max(x, y).
there is some implicit conversion (float to int), when call float type max function.So you need specify that.
max(5.9f, 6.7f)

Passing parameters to function pointer

I am trying to pass parameters to a function pointer being passed as a parameter.
Code:
void Test(wchar_t* a, wchar_t* b)
{
// ...
}
void Test2(void(*Func)(wchar_t*, wchar_t*))
{
// ...
}
int main()
{
Test2(Test(L"Hello", L"Testing"));
return 0;
}
I am getting this error:
argument of type "void" is incompatible with parameter of type "void (*)(wchar_t *, wchar_t *)"
How do I fix this to accomplish what I'm trying to achieve?
Edit: Sorry for not being clear. What I'm actually trying to accomplish is inject a function into a child process and pass two parameters (wchar_t*, wchar_t*) so I can use them. But the main function can either be void or int argc, char** argv. So I accomplished what I'm trying to achieve by simply using global variables
You probably want to have something like
void Test2(void(*Func)(wchar_t*, wchar_t*),wchar_t* x, wchar_t* y)
{
(*Func)(x,y);
}
int main()
{
Test2(Test,L"Hello", L"Testing");
return 0;
}
instead.
As for your comment
How do i do this in C++ with templates?
I could think of
template<typename Param>
void Test2(void(*Func)(Param, Param), Param x, Param y) {
(*Func)(x,y);
}
void Test(wchar_t* a, wchar_t* b);
int main() {
Test2(Test,L"Hello", L"Testing");
return 0;
}
This should just work fine.
There are more than one way to fix tihs issue, however, let me just try to show why this error is occuring.
Every function has a type of value associated with it. This means, that every function evaluates to a value of some type. This is indicated by its return value.
For example:
int foo(/*whatever*/);
evaluates to an int. So foo(/*whatever*/) can be used anywhere an int is expected. For example like int a = b + foo(/*whatever*/).
Simlarly float bar(/*whatever*/); evaluates to a float, hence bar(/*whatever*/) can be used anywhere a float is expected. For example like float a = b + bar(/*whatever*/).
A function that returns void like void foobar(/*whatever*/) however, evaluates to void and cannot be used where a value of some type (say int, float, etc) is expected.
Now coming to code. This line in your main function has the issue:
int main()
{
Test2(Test(L"Hello", L"Testing")); /* Issue here */
return 0;
}
Here you are passing Test(L"Hello", L"Testing") as the argument to Test2. Now remember, that Test(/*whatever*/), evaluates to a void because Test returns a void.
So what you are doing in that line is something like
Test2(/*something that evaluates to a void*/);
However, Test2 expectes a void (*)(wchar_t*, wchar_t*), which is a pointer to a function that returns void, which is different from void.
So what is happening, is that the compiler is seeing that you are passing a void in a place where a void (*) (wchar_t*, wchar_t*) is expected, so it is correctly indicating that error.
There can be different ways to solve this issue which are mentioned in other answers.
Do I need to use C++ templates?
Of course, you can do that using C++ templates as it follows:
#include<utility>
// ...
template<typename F, typename... A>
void Test2(F &&f, A&&... a)
{
std::forward<F>(f)(std::forward<A>(a)...);
// ...
}
// ...
Test2(Test, L"Hello", L"Testing");
But you don't need them to do what you are trying to do.
#πάνταῥεῖ has already explained why in its answer.

C++, different function output when called multiple times

I have the following code:
int countLatticePoints(const double radius, const int dimension) {
static std::vector<int> point {};
static int R = static_cast<int>(std::floor(radius));
static int latticePointCount = 0;
for(int i = -R; i <= R; i++) {
point.push_back(i);
if(point.size() == dimension) {
if(PointIsWithinSphere(point,R)) latticePointCount++;
} else {
countLatticePoints(R, dimension);
}
point.pop_back();
}
return latticePointCount;
}
When I make the call countLatticePoints(2.05, 3) I get the result 13 which is correct. Now I change the parameters and then call countLatticePoints(25.5, 1) I get 51 which is also correct.
Now when I call countLatticePoints(2.05, 3) and countLatticePoints(25.5, 1) right after each other in the main program I get 13 and then 18 (instead of 51), I really don't understand what i'm doing wrong ? When I call each one individually without the other I get the correct result but when I call the functions together one after the other my results change.
You're misusing static.
The second time you call the function, you push additional values into point.
Edit: I hadn't spotted the recursion. that makes things more complex, but static is still the wrong answer.
I'd create a 'state' object, and split the function into two. One that recurses, and takes a reference to the 'state' object, and a second one which initialises the state object and calls the first.
struct RecurState
{
std::vector<int> point;
int latticePointCount
RecurState() : latticePointCount(0)
{
}
}
Outer function:
int countLatticePoints(const double radius, const int dimension)
{
RecurState state;
return countLatticeRecurse(radius, dimension, state)
}
Recursive function
int countLatticeRecurse(const double radius, const int dimension, RecurseState &state)
{
...
}
Local, static variables only get initialized once, on the first function call.

A function that has been defined cannot be called in the main (C++)

I am learning about functions in C++, and I am trying to create a small function that swaps two values. However, when I try to call this function in the main, I get the error - "No matching function for call to 'swapfunction'". What am I doing wrong?
Here is the code:
#include <iostream>
using namespace std;
void swapfunction (double &x,double &y) {
double z(0);
z=y;
y=x;
x=z;
}
int main() {
int a(0);
int b(1);
swapfunction (a,b);
cout<<"a="<<a<<endl;
cout<<"b="<<b<<endl;
}
swapfunction's parameters are references to doubles, which means that the arguments have to be double objects. A double& reference cannot refer to an int object.
If the arguments were double rather than double&, the call would be legal, and the values of a and b would be implicitly converted from int to double -- but then the function couldn't update a and b.
You need to define objects of type double to pass to the function.

C++ pass a function as argument

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.