C++ variable and function - c++

so in my main function, I have a called function with arguments stored in a variable. I run my program, and the variable containing the function is executed. I thought that when I store functions or anything in a variable, then it shouldn't execute until I tell it to.
for example:
int cycle1 = cycleList(argument1, argument2);
this statement above is now executed on my screen. Is this a correct way to write code? I wanted to store the function in a variable, and later use the variable somewhere in my code.

If you want to store a function, you need to make a pointer to the function, not call the function, which is what you're doing. Try this instead:
#include <functional>
std::function<int (int, int)> cycle1 = cycleList;
Or, if you don't have access to C++11, try this:
int (*cycle1)(int, int) = cycleList;
Then later you can call:
cycle1(argument1, argument2);

If you wanted to store the result of the function at that point in time in the program's runtime, then yes, you are doing it correctly.

Functions can accept parameters and can return a result. Where the functions are declared in your program does not matter, as long as a functions name is known to the compiler before it is called.
Let’s take a look at an example;
int Add(int num1, int num2)
{
return num1 + num2;
}
int main()
{
int result, input1, input2;
cout << "Give a integer number:";
cin >> input1;
cout << "Give another integer number:";
cin >> input2;
result = Add(input1,input2);
cout << input1 << " + " << input2 << " = " << answer;
return 0;
}
Here I defined Add() function before main() so main knows that Add() is defined. So in main() when add() calls it sends two parameter and get results with return num1+ num2 . Then it sends returned value to result.

As far as what I can get from your query is that you are calling a parameterized method in your class which is returning some value. You want to store the result of that method in a variable so that you can use it as per your need. But, you want to eliminate the overhead of computing that method even when you don't need it. It should be executed only when you require it or on the basis of a particular condition.
What I can suggest you in this case is, have this code in a condition. There must be an appropriate time or a satisfied condition when you want that method to execute and compute the result for you.
For instance:
public class BaseCondition {
public int compute(int a, int b) {
return (a + b);
}
public boolean set(boolean flag) {
flag = true;
return flag;
}
public int subtract(int a, int b) {
return (a - b);
}
public int callCompute(int a, int b) {
boolean flag = false;
int computedVal = 0;
if (a < b || a == b) {
flag = set(flag);
}
if (flag) {
computedVal = compute(a, b);
} else {
computedVal = subtract(a, b);
}
return computedVal;
}
public static void main(String[] args) {
BaseCondition obj = new BaseCondition();
int a = 11;
int b = 51;
System.out.println("Result=" + obj.callCompute(a, b));
}
}
Here, you can find compute will be called only on the basis of flag which is being set only when a condition is satisfied.
Hope it helps :)

You can also do the following using auto's
#include <iostream>
using namespace std;
int Foo()
{
return 0;
}
int main()
{
// your code goes here
auto bar = Foo;
return 0;
}

In C++, variables store values, not functions; and an expression that calls a function to get a value does so immediately. So your example calls the function to get an int value, then stores that value in the variable.
There are ways to do what you want:
// Store a lambda function object, capturing arguments to call it with.
// This doesn't call the function.
auto cycle1 = [=]{cycleList(argument1, argument2);};
// Call the function later. This calles 'cycleList' with the captured arguments.
int result = cycle1();
but you should probably learn the basics before doing this sort of thing.

Functions return results, and function objects can be stored (and copied around) themselves, including their arguments:
#include <iostream>
int cycleList(int arg1, int arg2) { return arg1 + arg2; }
struct cycleListObj
{
int arg1, arg2;
// constructor stores arguments for later use
cycleListObj(int a1, int a2): arg1(a1), arg2(a2) {}
// overload function call operator()
int operator()() { return arg1 + arg2; }
};
int main()
{
int result1 = cycleList(1, 1); // stores 2 into result1
cycleListObj fun(1, 1); // defines a function object fun with arguments 1, 1
int result2 = fun(); // calls the function object, and stores the result into result2
std::cout << result1 << result2; // outputs 22
}
Live Example
As others have shown, the C++ Standard Library defines its own generic function object std::function, but for many purposes you can define them yourself as well.
You can also store function pointer, but then you still have to supply the arguments at the call site. With a function object, you can store the arguments first, and call it later.

Related

Assigning a values to a function argument in c++ in the order which it is defined

When passing a value to a function with multiple arguments which contains some default values how would I let my function know that this value is supposed to be for the last argument?
For example in the code
int myFun(int a, int b=2,ofstream &file) {
file<<"Hello please write this to a file"<<"\n";
int r;
r=a/b;
return (r);
}
int main () {
ofstream file("input.txt");
cout << myFun(12,3,file)<< '\n';
cout << myFun(20, ,file) << '\n'; //This doesn't work
return 0;
}
How would I let my program know that the value 4 is supposed to be for C and not for B?
You cannot do that. Default arguments have to be provided starting from the right. You cannot have default arguments for the second but none for the third.
One workaround is to encapsulte the parameters in a data structure:
struct myFunParameters {
int a = 0;
int b = 2;
std::ofstream& file;
};
And change signature to:
int myFun(myFunParameters f);
The caller can then use the defaults or provide custom values in any order they wish.
Alternatively remove the default arguments and use an overload:
int myFun(int a, int b,ofstream &file);
int myFun(int a,ostrstream& file) { return myFun(a,2,file); }

Is it safe to pass lambda to function that is going out of scope (lambda executes after the method returns)?

I am learning C++ so maybe my question is dumb. I am creating a function that takes a lambda as a parameter. I just want to know if its safe to call it when the lambda function goes out of scope. With code is easier to explain what I mean:
struct SomeStruct
{
// store pointer to callback function
void (*callback)(bool);
int arg1;
int arg2;
};
void some_method(int arg1, int arg2, void (*on_complete_callback)(bool))
{
SomeStruct s;
s.callback = on_complete_callback;
s.arg1 = arg1;
s.arg2 = arg2;
// this helper class will copy the struct even though it is passed by reference
SomeHelperClass->SomeQueue.enqueue( &s );
// do work on a separate task/thread
SomeHelperClass->CreateThread([](){
// get copy of struct
SomeStruct s_copy;
SomeHelperClass->SomeQueue.dequeue( &s_copy );
// do work that takes time to complete
// IS IT SAFE TO CALL THIS CALLBACK FUNCTION?
s_copy.callback(true);
});
}
So my question is given that code if its safe to have something like this?
void method_1()
{
void (*foo)(bool) = [](bool completedCorrectly)
{
cout << "task completed :" << completedCorrectly << endl;
};
some_method(1,2,foo);
// at this point foo should be deleted no?
// why does this work if foo is executed after method_1 completes and its stack is deleted?
// can I have code like that?
}
Edit 2
Here is the same question with working code instead of pseudo code:
#include <iostream> //for using cout
using namespace std; //for using cout
// 3 pointers
int* _X; // points to integer
int* _Y; // points to integer
void (*_F)(int); // points to function
void print_values()
{
cout << "x=" << *_X << " and y=" << *_Y << endl;
}
void some_function()
{
// create variables that live on stack of some_function
int x = 1;
int y = 2;
void (*foo)(int) = [](int someInt)
{
cout << "value passed to lambda is:" << someInt << endl;
};
// point global variables to variables created on this stack x,y and foo
_X = &x;
_Y = &y;
_F = foo;
// works
_F(11);
// works
print_values();
// when exiting variables x,y and foo should be deleted
}
int main(void)
{
// call some function
some_function();
// DOES NOT WORK (makes sense)
print_values();
// WHY DOES THIS WORK? WHY FOO IS NOT DISTROYED LIKE X AND Y?
_F(10);
return 0;
}
If I where to call that method many times and each time with a different lambda will it work? Will the callback method call the correct lambda every time?
A lambda expression is like a class. It is a blueprint for instantiating objects. Classes exist only in source code. A program actually works with objects created from the blueprint defined by a class. Lambda expressions are a source code blueprint for creating closures. Each lambda expression is transformed into a class by the compiler and instantiated into an object called closure. This class has the ability to capture values (that's that the [] part does) and take parameters (that's that the () part does) for its call operator.
Here is an example:
int main()
{
int i = 42;
auto l = [i](int const x){std::cout << x+i << '\n';};
l(2);
}
The compiler transforms this into something similar to the following (generated with https://cppinsights.io/).
int main()
{
int i = 42;
class __lambda_6_11
{
public:
inline /*constexpr */ void operator()(const int x) const
{
std::operator<<(std::cout.operator<<(x + i), '\n');
}
private:
int i;
public:
__lambda_6_11(int & _i)
: i{_i}
{}
};
__lambda_6_11 l = __lambda_6_11{i};
l.operator()(2);
}
You can see here a class that implements the call operator (operator()) with an int argument. You can also see the constructor taking an argument of type int. And then you can see the instantiation of this class at the end of main and the invocation of its call operator.
I hope this helps you understand better how lambdas work.

Function returning unexpected struct values

I am completely new to structs and user defined datatypes, and i was trying to create a function that returns a struct:
The problem is highlight by the comment:
#include <iostream>
using namespace std;
struct num {
int n[2];
};
num func( num x, int a, int b) {
x.n[0] = a+b;
x.n[1] = a*b;
return x;
}
int main() {
int x,y;
num s1;
cout << "enter: ";
cin >> x >> y;
func(s1,x,y);
cout << s1.n[0] << "\n" << s1.n[1]; // THIS GIVES ERROR
cout << func(s1,x,y).n[0] << "\n" << func(s1,x,y).n[1]; // THIS DOENST GIVE ERROR
return 0;
}
I understand that second method makes sense and returns the struct variable. then putting a dot addresses the inner variable of struct.
But i dont understand why first method fails, or gives odd output. The function has done its job, ie made s1.n[0] = x + y and s1.n[1] = x*y
Now, printing s1.n[0] should print x + y only. How can we check and correct the internal workings of the function?
You have to assign the returned value to the structure object in main
s1 = func(s1,x,y);
Inside the body the function deals with a copy of the original object. It does not change the original object because it is passed by value.
Another approach is to pass the structure by reference
void func( num &x, int a, int b) {
x.n[0] = a+b;
x.n[1] = a*b;
}
In this case in main you could just write
func(s1,x,y);
Or you could use even so-called C approach of passing by reference
void func( num *x, int a, int b) {
x->n[0] = a+b;
x->n[1] = a*b;
}
and call it like
func( &s1, x, y );
As for this statement
cout << func(s1,x,y).n[0] << "\n" << func(s1,x,y).n[1];
then you access data members of two temporary objects returned by the two calls of the function. After executing this statement these temporary objects will be deleted.
It looks like you are never assigning the return value of func(). Your function returns the struct, but you are never assigning it. To fix this, you should be able to simply say: s1 = func(s1,x,y); This will assign the modified version of the struct to the s1 variable.
Alternatively, you could rewrite func() to accept a pointer to the struct. This would allow you to modify the struct without having to return it:
void func( num *x, int a, int b) {
x->n[0] = a+b;
x->n[1] = a*b;
}
Then you would just change your call to func() to say: func(&s1, x, y);
You are not passing your struct by reference, hence the result. Try the following:
void func(num &x, int a, int b) {
x.n[0] = a+b;
x.n[1] = a*b;
}
There's no need for the function to return anything since your struct is passed by reference and it will be changed anyway. Void would fit better.
This is because you have passed the struct by value while your intentions look like you want to pass by reference.
Check this link : http://courses.washington.edu/css342/zander/css332/passby.html
num func( num &x, int a, int b)
should fix your problem

C++ Update Function Argument

I have a function defined with several parameters passed by value. Both the function and inputs for the parameters depend on a common global variable. I need some way to get my function to re-evaluate the inputs of its parameters while executing within its own scope. Here is a simplified version of the code.
#include <iostream>
using namespace std;
int Sum(int arg1, int from, int to);
int i;
int func();
int main(int argc, char *argv[])
{
Sum(func(), 0, 10);
return 0;
}
int Sum(int arg1, int from, int to)
{
int out = 0;
for (i = from; i <= to; i++)
{
out += arg1;
cout << "arg1 = " << arg1 << ", out = " << out << endl;
}
return out;
}
int func()
{
return i;
}
Some highlights:
* Here I am trying to update the input values for parameter arg1 on function Sum().
Normally, I would solve this problem by defining the parameter by reference (in this case, the parameter is arg1 in function Sum).
However, because the method in which I use this function normally involves combining multiple input values inline, I have to pass by value.
Is there some way to define a temporary unnamed function inline with the inputs for Sum? Then I could pass parameters by reference and solve my troubles. Or any other ideas for how to make this work?
Thanks!
This is a place you could use a function pointer. Instead of passing func(), you pass simply func, and call it from within your function:
int Sum(int (*func_arg1)(void), int from, int to)
{
int out = 0;
for (i = from; i <= to; i++)
{
int arg1 = func_arg1();
out += arg1;
cout << "arg1 = " << arg1 << ", out = " << out << endl;
}
return out;
}
The syntax for function pointers is a bit unusual in C and C++. The declaration int (*func_arg1)(void) declares a symbol named func_arg1 that is a pointer to a function taking no arguments, but returning int. In this case, that symbol is also the first argument of Sum.
The only other changes you need to make to your program are the prototype for Sum to match the function above, and to call Sum as follows:
Sum(func, 0, 10);

Functions in different files not working properly

I made a program that calls this function. I know this because "Int Strength has been called" appears in the output box. However, it will not change the values that I tell it to do.
I want it to get integer values from main(), then use them and return the new values.
I am using a header file that only contains "int strength(int a, int s, int i)"
int strength(int a, int s, int i)
{
using namespace std;
cout << "Int Strength has been called" << endl;
a = a + i;
s = s - i;
return a;
return s;
}
Multiple errors. Firstly, if you want the arguments to be modified (more precisely, the modification being effective out of the scope of the function), you have to pass the values by reference:
int strength(int &a, int &s, int &i)
Second, you seem to be concerned about return a; return s; returning two values. It doesn't - the very first return encountered exits the function immediately.
The values only change within the function. Variables are passed by value not reference.
Use references as the parameters.
int strength(int& a, int& s, int& i)
You're passing by value. You need to pass a pointer to the memory allocated in the caller that contains the data you wish to modify.
void strength(int *a, int *s, int i)
{
using namespace std;
cout << "Int Strength has been called" << endl;
*a += i;
*s -= i;
}
Then call it thusly:
a = 1;
s = 2;
i = 3;
strength(&a, &s, i);