I want to create a general function which returns a function pointer to another function in C/C++. However, second returned function should be able to use variable from first function.
Example,
typedef double (*func_t)(double);
func_t inverse(func_t fn) {
// define another function here that uses fn
double solve(double x) {
// use fn
}
return &solve;
}
double sqr(double x) { return x * x; }
int main() {
func_t inv = inverse(sqr);
printf("sqrt %d = %f\n", 100, inv(100));
}
Obviously gcc, g++ do not allow me to do this. Can I achieve this without using classes or structs.
This is not about nested functions; this is about closures. GCC's nested functions are a half-implemented form of closure that does not do what the question is asking for.
C, going by any of the standards, does not support closures at all.
C++11 supports closures through lambdas, and there are a few other solutions specific to C++ as well.
Apple's Clang compiler does support closures as an extension in C mode, in the form of "blocks". Unlike nested functions, these actually work for the requested use case (i.e. being returned to a higher call level).
You'd write it out something like this:
typedef double (^func_t)(double); // block type is slightly different from function pointer
func_t inverse(func_t fn) {
return ^ double(double x) {
//use fn
};
}
// ...etc., same from here
But if you want to make extensive use of closures, you really need to use a different language. You'll run into serious complications in C because of the lack of any kind of memory management (unrestricted closures are a nightmare to manage by hand).
Answering for C:
C does not support nested functions (defining a function inside another function) but gcc
allows it as a GNU extension to C.
http://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html
This is possible in C++11 with a lambda:
#include <cstdio>
#include <cmath>
#include <functional>
typedef std::function<double(double)> func_t;
func_t inverse(func_t fn) {
return [=](double x) { printf("fn(x): %f\n", fn(x)); return sqrt(x); };
}
double sqr(double x) { return x * x; }
int main() {
auto inv = inverse(sqr);
printf("sqrt %d = %f\n", 100, inv(100));
}
If you can use C++11, them lambda functions are your friend:
#include <functional>
#include <iostream>
std::function<double(double)> identity(std::function<double(double)> fn)
{
return [fn](double x){
// Do your logic here
return fn(x);
};
}
double sqr(double x) { return x * x; }
int main() {
auto f = identity(sqr);
std::cout << "sqr(100) = " << f(100) << std::endl;
}
If you don't plan to support C++11, you can do this way:
#include <iostream>
typedef double (*func_t)(double);
struct func
{
func_t fn;
double (*calc)(func_t, double);
double operator()(double x) {return calc(fn, x);}
};
double identity_calc(func_t fn, double x) {return fn(x);}
func identity(func_t fn)
{
func f = {fn, identity_calc};
return f;
}
double sqr(double x) { return x * x; }
int main() {
func f = identity(sqr);
std::cout << "sqr(100) = " << f(100) << std::endl;
}
But I don't think you will have much luck with plain C.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With