Home > Back-end >  How do I save a function pointer for later use in c , similar closures that have a saved state
How do I save a function pointer for later use in c , similar closures that have a saved state

Time:11-24

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();
}

Live demo


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()>

  • Related