I am a c newbie so I'm not sure how to write this, but basically I want a function that takes in a few parameters and returns a function pointer that does not need any parameters and can be executed for later use. Exactly like a closure.
I know c does not have closures, but can get some of the same effects with lambda expessions. I'm just not sure if it can do what I want it to do. Again I don't know much c . I have been going through tutorials and reading posts about how lambdas work in c , but I can't figure out how do get this code to work.
Here is some example code of what I'm trying to in typescript
let myVariable;
const myClosure = (param1: number, param2: number, param3, string, ) => {
return () => {
// Do something with params
console.log(param1, param2, param3);
}
}
function whereInitalized() {
myVariable = myClosure(1,2,"name");
}
function whereExecuted() {
myVariable(); // prints the params
}
whereInitalized();
whereExecuted();
This is what I want in c , but it's wrong
// Not correct syntax or type
// Having trouble getting typing for this variable;
std::function<void(param1: T, param2: P, param3: V)> (*myVariable)() = myClosure;
std::function<void()> myClosure(param1: T, param2: P, param3: V) {
return []() { // Returns a function that does not take a parameter
param1.someMethod();
param2->Call(blah, blah);
// ... More work
};
}
void functionWhereInitalized() {
myVariable = myClosure(param1, param2, param3);
}
void functionWhereExecuted() {
myVariable();
}
And here is what I have in c , works, but cannot take in parameter
std::function<void()> myVariable = myClosure;
std::function<void()> myClosure() {
return [num = 99]() mutable {
// Test code to see it gets called
num ;
std::cout << num << " -- " << "\n";
};
}
void functionWhereInitalized() {
myVariable = myClosure();
}
void functionWhereExecuted() {
myVariable();
}
I appreciate any responses in advance!
CodePudding user response:
Before answering the technical question, a note from Sam Varshavchik I agree with:
You say that you "don't know much c ". Unfortunately, the very first thing you will learn about C is that it is not about instant gratification. It takes time to learn it, a long time. You are describing one of the basic templates from the C library, but to get there it's necessary to study, and learn, core C fundamentals, for about a year or two, before reaching its advanced topics, like templates. Any attempt to short-circuit the process will, eventually, always end in tears. C is just too complicated to be learned by asking one question at a time, on Stackoverflow.
Now for the technical question: you can acheive simple closures as described here with lambda captures1:
#include <iostream>
#include <string_view>
auto make_closure(std::ostream& out, std::string_view message, int repeat=1)
{
return [&out,repeat,message]() mutable { while (repeat --> 0) out << message; };
}
int main(){
auto say_hello = make_closure(std::cout, "Hello\n", 2);
say_hello();
}
1)
The captures is a comma-separated list of zero or more captures, optionally beginning with the capture-default. The capture list defines the outside variables that are accessible from within the lambda function body. The only capture defaults are
&
(implicitly capture the used automatic variables by reference) and=
(implicitly capture the used automatic variables by copy). The current object (*this
) can be implicitly captured if either capture default is present. If implicitly captured, it is always captured by reference, even if the capture default is=
. The implicit capture of*this
when the capture default is=
is deprecated. (since C 20)
CodePudding user response:
std::function<void(param1: T, param2: P, param3: V)> (*myVariable)() = myClosure;
I'm not rly sure what's going on in here. my wild guess would be you want to do something like this
std::function<void()> yourClosure(T1 const& p1, T2 const& p2, T3 const& p3)
{
return [p1, p2, p3]() { /* do the thing */};
}
but if you just want to store function for later use you can actually either
auto const function = [a,b,c](){ /* meaningful code*/ };
or
some_types... a, b, c; // whatever variables you have
auto const function_with_params = [](auto const& a, auto const& b, auto const&c){ /* skrnyr dgdyr */};
auto const function_with_bound_params = std::bind(function_with_params, a, b, c);
both lambda version and binding version should be cast-able to std::function<void()>