How has the functor below to be altered to work as a lambda wrapper?
template<typename T>
class F {
T f;
public:
F(T t){
f = t;
}
T& operator()(){
return f;
}
};
int main()
{
int x = 5;
F<int (*)(int, int)> f( [x](int a, int b){return a+b;} );
return 0;
}
The compiler says
error: no matching function for call to 'F<int (*)(int, int)>::F(main()::<lambda(int, int)>)'
F<int (*)(int, int)> f( [x](int a, int b){return a+b;} );
It's more complicated... Internally lambda functions that capture variables are not functions as such, are data structures. I not found any solution developed and many requests and questions unresolved, then I developed this minimal code to wrap lambda pointer not using std::function or any other standard function or dependence. Pure c++11.
Accepts all kinds of lambda captures, arguments by reference, return void, and supports top level functions and member methods.
// Type checkers
template<typename _Type>
struct IsVoid
{
static const bool value = false;
};
template<>
struct IsVoid<void>
{
static const bool value = true;
};
// Callable signature interfce
template<typename _ReturnType, typename..._ArgTypes>
struct Callable
{
typedef _ReturnType ReturnType;
typedef _ReturnType (*SignatureType)(_ArgTypes...);
virtual _ReturnType operator()(_ArgTypes...args) = 0;
};
// Function and lambda closure wrapper
template<typename _ClosureType, typename _ReturnType, typename..._ArgTypes>
struct Closure: public Callable<_ReturnType, _ArgTypes...>
{
typedef _ClosureType ClosureType;
const _ClosureType closureHandler;
Closure(const _ClosureType& handler)
: closureHandler(handler)
{
}
_ReturnType operator()(_ArgTypes...args) override
{
if(IsVoid<_ReturnType>::value)
closureHandler(args...);
else
return closureHandler(args...);
}
};
// Fuction template selector
template <typename _FunctionType>
class Function
: public Function<decltype(&_FunctionType::operator())>
{
};
// Function, lambda, functor...
template <typename _ReturnType, typename... _ArgTypes>
class Function<_ReturnType(*)(_ArgTypes...)>
{
public:
typedef Function<_ReturnType(*)(_ArgTypes...)> SelfType;
typedef _ReturnType(*SignatureType)(_ArgTypes...);
Callable<_ReturnType, _ArgTypes...>* callableClosure;
Function(_ReturnType(*function)(_ArgTypes...))
: callableClosure(new Closure<SignatureType, _ReturnType, _ArgTypes...>(function))
{
}
// Captured lambda specialization
template<typename _ClosureType>
Function(const _ClosureType& function)
: callableClosure(new Closure<decltype(function), _ReturnType, _ArgTypes...>(function))
{
}
_ReturnType operator()(_ArgTypes... args)
{
if(IsVoid<_ReturnType>::value)
(*callableClosure)(args...);
else
return (*callableClosure)(args...);
}
};
// Member method
template <typename _ClassType, typename _ReturnType, typename... _ArgTypes>
class Function<_ReturnType(_ClassType::*)(_ArgTypes...)>
{
public:
typedef Function<_ReturnType(_ClassType::*)(_ArgTypes...)> SelfType;
typedef _ReturnType(_ClassType::*SignatureType)(_ArgTypes...);
SignatureType methodSignature;
Function(_ReturnType(_ClassType::*method)(_ArgTypes...))
: methodSignature(method)
{
}
_ReturnType operator()(_ClassType* object, _ArgTypes... args)
{
if(IsVoid<_ReturnType>::value)
(object->*methodSignature)(args...);
else
return (object->*methodSignature)(args...);
}
};
// Const member method
template <typename _ClassType, typename _ReturnType, typename... _ArgTypes>
class Function<_ReturnType(_ClassType::*)(_ArgTypes...) const>
{
public:
typedef Function<_ReturnType(_ClassType::*)(_ArgTypes...) const> SelfType;
typedef _ReturnType(_ClassType::*SignatureType)(_ArgTypes...) const;
SignatureType methodSignature;
Function(_ReturnType(_ClassType::*method)(_ArgTypes...) const)
: methodSignature(method)
{
}
_ReturnType operator()(_ClassType* object, _ArgTypes... args)
{
if(IsVoid<_ReturnType>::value)
(object->*methodSignature)(args...);
else
return (object->*methodSignature)(args...);
}
};
Tests:
#include <iostream>
class Foo
{
public:
int bar(int a, int b)
{
return a + b;
}
};
int someFunction(int a, int b)
{
return a + b;
}
int main(int argc, char** argv)
{
int a = 10;
int b = 1;
// Lambda without capturing
Function<int(*)(int)> fn1([] (int b) -> int {
return b;
});
std::cout << fn1(2) << std::endl; // 2
// Lambda capturing variable
Function<int(*)(int)> fn2([a] (int c) -> int {
return a + c;
});
std::cout << fn2(-7) << std::endl; // 3
// Lambda capturing scope
Function<int(*)(int)> fn3([&] (int c) -> int {
return a + c;
});
std::cout << fn3(-5) << std::endl; // 5
// Arguments by reference
Function<void(*)(int&, int)> fn4([] (int& d, int f) {
d = d + f;
});
fn4(a, -3); // Void call
std::cout << a << std::endl; // 7
// Top level function reference
Function<int(*)(int, int)> fn6(someFunction);
std::cout << fn6(a, 4) << std::endl; // 11
// Member method
Foo* foo = new Foo();
Function<int(Foo::*)(int,int)> fn7(foo->bar);
std::cout << fn7(foo, a, 8) << std::endl; // 15
}
Works correctly wih gcc 4.9.
Thanks for your question.
A lambda can't directly be converted to a free function pointer if it captures something just because they are two different things.
A lambda with capturing values must save its state somewhere, but a function pointer is just a memory address thus it doesn't provide that functionality. So you would be allowed to do something
static_cast<int(*)(int,int)>([](int a, int b) { return a+b; })
but that's not your case.
Some solutions could be:
don't use a function pointer but use a std::function<int(int,int>) instead
provide a free function which invokes the lambda (not a good solution in your case, mostly meant to be used to inerface with legacy code I'd say
use a template function which provides the wrapping from lambda to function pointer by itself. Similar to the solution proposed here
Use simple workaround with decltype.
auto lambda = [x](int a, int b){return a+b;};
F<decltype(lambda)> f(lambda); // OK
To make it look concise, we can use macro:
#define DECLARE_F(OBJECT, LAMBDA) \
auto lambda = LAMBDA; \
F<decltype(lambda)> OBJECT(lambda)
Usage:
DECLARE_F(f, [x](int a, int b){return a+b;}); // 1 per line if used ## __LINE__
Related
I was playing with C++ lambdas and their implicit conversion to function pointers. My starting example was using them as callback for the ftw function. This works as expected.
#include <ftw.h>
#include <iostream>
using namespace std;
int main()
{
auto callback = [](const char *fpath, const struct stat *sb,
int typeflag) -> int {
cout << fpath << endl;
return 0;
};
int ret = ftw("/etc", callback, 1);
return ret;
}
After modifying it to use captures:
int main()
{
vector<string> entries;
auto callback = [&](const char *fpath, const struct stat *sb,
int typeflag) -> int {
entries.push_back(fpath);
return 0;
};
int ret = ftw("/etc", callback, 1);
for (auto entry : entries ) {
cout << entry << endl;
}
return ret;
}
I got the compiler error:
error: cannot convert ‘main()::<lambda(const char*, const stat*, int)>’ to ‘__ftw_func_t {aka int (*)(const char*, const stat*, int)}’ for argument ‘2’ to ‘int ftw(const char*, __ftw_func_t, int)’
After some reading. I learned that lambdas using captures can't be implicitly converted to function pointers.
Is there a workaround for this? Does the fact that they can't be "implicitly" converted mean s that they can "explicitly" converted? (I tried casting, without success). What would be a clean way to modify the working example so that I could append the entries to some object using lambdas?.
I just ran into this problem.
The code compiles fine without lambda captures, but there is a type conversion error with lambda capture.
Solution with C++11 is to use std::function (edit: another solution that doesn't require modifying the function signature is shown after this example). You can also use boost::function (which actually runs significantly faster). Example code - changed so that it would compile, compiled with gcc 4.7.1:
#include <iostream>
#include <vector>
#include <functional>
using namespace std;
int ftw(const char *fpath, std::function<int (const char *path)> callback) {
return callback(fpath);
}
int main()
{
vector<string> entries;
std::function<int (const char *fpath)> callback = [&](const char *fpath) -> int {
entries.push_back(fpath);
return 0;
};
int ret = ftw("/etc", callback);
for (auto entry : entries ) {
cout << entry << endl;
}
return ret;
}
Edit:
I had to revisit this when I ran into legacy code where I couldn't modify the original function signature, but still needed to use lambdas. A solution that doesn't require modifying the function signature of the original function is below:
#include <iostream>
#include <vector>
#include <functional>
using namespace std;
// Original ftw function taking raw function pointer that cannot be modified
int ftw(const char *fpath, int(*callback)(const char *path)) {
return callback(fpath);
}
static std::function<int(const char*path)> ftw_callback_function;
static int ftw_callback_helper(const char *path) {
return ftw_callback_function(path);
}
// ftw overload accepting lambda function
static int ftw(const char *fpath, std::function<int(const char *path)> callback) {
ftw_callback_function = callback;
return ftw(fpath, ftw_callback_helper);
}
int main() {
vector<string> entries;
std::function<int (const char *fpath)> callback = [&](const char *fpath) -> int {
entries.push_back(fpath);
return 0;
};
int ret = ftw("/etc", callback);
for (auto entry : entries ) {
cout << entry << endl;
}
return ret;
}
Since capturing lambdas need to preserve a state, there isn't really a simple "workaround", since they are not just ordinary functions. The point about a function pointer is that it points to a single, global function, and this information has no room for a state.
The closest workaround (that essentially discards the statefulness) is to provide some type of global variable which is accessed from your lambda/function. For example, you could make a traditional functor object and give it a static member function which refers to some unique (global/static) instance.
But that's sort of defeating the entire purpose of capturing lambdas.
ORIGINAL
Lambda functions are very convenient and reduce a code. In my case I needed lambdas for parallel programming. But it requires capturing and function pointers. My solution is here. But be careful with scope of variables which you captured.
template<typename Tret, typename T>
Tret lambda_ptr_exec(T* v) {
return (Tret) (*v)();
}
template<typename Tret = void, typename Tfp = Tret(*)(void*), typename T>
Tfp lambda_ptr(T& v) {
return (Tfp) lambda_ptr_exec<Tret, T>;
}
Example
int a = 100;
auto b = [&]() { a += 1;};
void (*fp)(void*) = lambda_ptr(b);
fp(&b);
Example with a return value
int a = 100;
auto b = [&]() {return a;};
int (*fp)(void*) = lambda_ptr<int>(b);
fp(&b);
UPDATE
Improved version
It was a while since first post about C++ lambda with captures as a function pointer was posted. As It was usable for me and other people I made some improvement.
Standard function C pointer api uses void fn(void* data) convention. By default this convention is used and lambda should be declared with a void* argument.
Improved implementation
struct Lambda {
template<typename Tret, typename T>
static Tret lambda_ptr_exec(void* data) {
return (Tret) (*(T*)fn<T>())(data);
}
template<typename Tret = void, typename Tfp = Tret(*)(void*), typename T>
static Tfp ptr(T& t) {
fn<T>(&t);
return (Tfp) lambda_ptr_exec<Tret, T>;
}
template<typename T>
static void* fn(void* new_fn = nullptr) {
static void* fn;
if (new_fn != nullptr)
fn = new_fn;
return fn;
}
};
Exapmle
int a = 100;
auto b = [&](void*) {return ++a;};
Converting lambda with captures to a C pointer
void (*f1)(void*) = Lambda::ptr(b);
f1(nullptr);
printf("%d\n", a); // 101
Can be used this way as well
auto f2 = Lambda::ptr(b);
f2(nullptr);
printf("%d\n", a); // 102
In case return value should be used
int (*f3)(void*) = Lambda::ptr<int>(b);
printf("%d\n", f3(nullptr)); // 103
And in case data is used
auto b2 = [&](void* data) {return *(int*)(data) + a;};
int (*f4)(void*) = Lambda::ptr<int>(b2);
int data = 5;
printf("%d\n", f4(&data)); // 108
Using locally global (static) method it can be done as followed
template <class F>
auto cify_no_args(F&& f) {
static F fn = std::forward<F>(f);
return [] {
return fn();
};
}
Suppose we have
void some_c_func(void (*callback)());
So the usage will be
some_c_func(cify_no_args([&] {
// code
}));
This works because each lambda has an unique signature so making it static is not a problem. Following is a generic wrapper with variadic number of arguments and any return type using the same method.
template <class F>
struct lambda_traits : lambda_traits<decltype(&F::operator())>
{ };
template <typename F, typename R, typename... Args>
struct lambda_traits<R(F::*)(Args...)> : lambda_traits<R(F::*)(Args...) const>
{ };
template <class F, class R, class... Args>
struct lambda_traits<R(F::*)(Args...) const> {
using pointer = typename std::add_pointer<R(Args...)>::type;
static pointer cify(F&& f) {
static F fn = std::forward<F>(f);
return [](Args... args) {
return fn(std::forward<Args>(args)...);
};
}
};
template <class F>
inline typename lambda_traits<F>::pointer cify(F&& f) {
return lambda_traits<F>::cify(std::forward<F>(f));
}
And similar usage
void some_c_func(int (*callback)(some_struct*, float));
some_c_func(cify([&](some_struct* s, float f) {
// making use of "s" and "f"
return 0;
}));
Hehe - quite an old question, but still...
#include <iostream>
#include <vector>
#include <functional>
using namespace std;
// We dont try to outsmart the compiler...
template<typename T>
int ftw(const char *fpath, T callback) {
return callback(fpath);
}
int main()
{
vector<string> entries;
// ... now the #ftw can accept lambda
int ret = ftw("/etc", [&](const char *fpath) -> int {
entries.push_back(fpath);
return 0;
});
// ... and function object too
struct _ {
static int lambda(vector<string>& entries, const char* fpath) {
entries.push_back(fpath);
return 0;
}
};
ret = ftw("/tmp", bind(_::lambda, ref(entries), placeholders::_1));
for (auto entry : entries ) {
cout << entry << endl;
}
return ret;
}
My solution, just use a function pointer to refer to a static lambda.
typedef int (* MYPROC)(int);
void fun(MYPROC m)
{
cout << m(100) << endl;
}
template<class T>
void fun2(T f)
{
cout << f(100) << endl;
}
void useLambdaAsFunPtr()
{
int p = 7;
auto f = [p](int a)->int {return a * p; };
//fun(f);//error
fun2(f);
}
void useLambdaAsFunPtr2()
{
int p = 7;
static auto f = [p](int a)->int {return a * p; };
MYPROC ff = [](int i)->int { return f(i); };
//here, it works!
fun(ff);
}
void test()
{
useLambdaAsFunPtr2();
}
There is a hackish way to convert a capturing lambda into a function pointer, but you need to be careful when using it:
https://codereview.stackexchange.com/questions/79612/c-ifying-a-capturing-lambda
Your code would then look like this (warning: brain compile):
int main()
{
vector<string> entries;
auto const callback = cify<int(*)(const char *, const struct stat*,
int)>([&](const char *fpath, const struct stat *sb,
int typeflag) -> int {
entries.push_back(fpath);
return 0;
});
int ret = ftw("/etc", callback, 1);
for (auto entry : entries ) {
cout << entry << endl;
}
return ret;
}
The answer made by #vladimir-talybin has a little problem:
template <class F>
auto cify_no_args(F&& f) {
static F fn = std::forward<F>(f);
return [] {
return fn();
};
}
That is, if the lambda is called twice in the function, then only the first call is valid, e.g.
// only a demo
void call(std::vector<int>& nums) {
static int i = 0;
cify_no_args([&]() {
nums.emplace_back(i++);
})();
}
int main() {
std::vector<int> nums1, nums2;
call(nums1);
call(nums2);
std::cout << nums1.size() << std::endl << nums2.size() << std::endl;
}
You will show the output of 2 and 0, which means that the second call of call function is using the first call's lambda closure.
That's because the solution is using the static to store the closure's reference, and once the reference is stored, it won't be changed, even for a new closure. Things get worse if the closure will get destructed (due to out of scope or else).
My solution of this problem is simply turning the reference into pointer, and update the pointer's value every time we "construct" the lambda:
template <class F>
auto cify_no_args(F&& f) {
static typename std::remove_reference<F>::type* fn;
fn = &f;
return [] {
return (*fn)();
};
}
The overhead is two more memory access, one for read and one for write, but ensures the correctness.
Found an answer here:
http://meh.schizofreni.co/programming/magic/2013/01/23/function-pointer-from-lambda.html
It converts lambda pointer to void* and convert back when needed.
to void*:
auto voidfunction = new decltype(to_function(lambda))(to_function(lambda));
from void*:
auto function = static_cast< std::function*>(
voidfunction);
I was playing with C++ lambdas and their implicit conversion to function pointers. My starting example was using them as callback for the ftw function. This works as expected.
#include <ftw.h>
#include <iostream>
using namespace std;
int main()
{
auto callback = [](const char *fpath, const struct stat *sb,
int typeflag) -> int {
cout << fpath << endl;
return 0;
};
int ret = ftw("/etc", callback, 1);
return ret;
}
After modifying it to use captures:
int main()
{
vector<string> entries;
auto callback = [&](const char *fpath, const struct stat *sb,
int typeflag) -> int {
entries.push_back(fpath);
return 0;
};
int ret = ftw("/etc", callback, 1);
for (auto entry : entries ) {
cout << entry << endl;
}
return ret;
}
I got the compiler error:
error: cannot convert ‘main()::<lambda(const char*, const stat*, int)>’ to ‘__ftw_func_t {aka int (*)(const char*, const stat*, int)}’ for argument ‘2’ to ‘int ftw(const char*, __ftw_func_t, int)’
After some reading. I learned that lambdas using captures can't be implicitly converted to function pointers.
Is there a workaround for this? Does the fact that they can't be "implicitly" converted mean s that they can "explicitly" converted? (I tried casting, without success). What would be a clean way to modify the working example so that I could append the entries to some object using lambdas?.
I just ran into this problem.
The code compiles fine without lambda captures, but there is a type conversion error with lambda capture.
Solution with C++11 is to use std::function (edit: another solution that doesn't require modifying the function signature is shown after this example). You can also use boost::function (which actually runs significantly faster). Example code - changed so that it would compile, compiled with gcc 4.7.1:
#include <iostream>
#include <vector>
#include <functional>
using namespace std;
int ftw(const char *fpath, std::function<int (const char *path)> callback) {
return callback(fpath);
}
int main()
{
vector<string> entries;
std::function<int (const char *fpath)> callback = [&](const char *fpath) -> int {
entries.push_back(fpath);
return 0;
};
int ret = ftw("/etc", callback);
for (auto entry : entries ) {
cout << entry << endl;
}
return ret;
}
Edit:
I had to revisit this when I ran into legacy code where I couldn't modify the original function signature, but still needed to use lambdas. A solution that doesn't require modifying the function signature of the original function is below:
#include <iostream>
#include <vector>
#include <functional>
using namespace std;
// Original ftw function taking raw function pointer that cannot be modified
int ftw(const char *fpath, int(*callback)(const char *path)) {
return callback(fpath);
}
static std::function<int(const char*path)> ftw_callback_function;
static int ftw_callback_helper(const char *path) {
return ftw_callback_function(path);
}
// ftw overload accepting lambda function
static int ftw(const char *fpath, std::function<int(const char *path)> callback) {
ftw_callback_function = callback;
return ftw(fpath, ftw_callback_helper);
}
int main() {
vector<string> entries;
std::function<int (const char *fpath)> callback = [&](const char *fpath) -> int {
entries.push_back(fpath);
return 0;
};
int ret = ftw("/etc", callback);
for (auto entry : entries ) {
cout << entry << endl;
}
return ret;
}
Since capturing lambdas need to preserve a state, there isn't really a simple "workaround", since they are not just ordinary functions. The point about a function pointer is that it points to a single, global function, and this information has no room for a state.
The closest workaround (that essentially discards the statefulness) is to provide some type of global variable which is accessed from your lambda/function. For example, you could make a traditional functor object and give it a static member function which refers to some unique (global/static) instance.
But that's sort of defeating the entire purpose of capturing lambdas.
ORIGINAL
Lambda functions are very convenient and reduce a code. In my case I needed lambdas for parallel programming. But it requires capturing and function pointers. My solution is here. But be careful with scope of variables which you captured.
template<typename Tret, typename T>
Tret lambda_ptr_exec(T* v) {
return (Tret) (*v)();
}
template<typename Tret = void, typename Tfp = Tret(*)(void*), typename T>
Tfp lambda_ptr(T& v) {
return (Tfp) lambda_ptr_exec<Tret, T>;
}
Example
int a = 100;
auto b = [&]() { a += 1;};
void (*fp)(void*) = lambda_ptr(b);
fp(&b);
Example with a return value
int a = 100;
auto b = [&]() {return a;};
int (*fp)(void*) = lambda_ptr<int>(b);
fp(&b);
UPDATE
Improved version
It was a while since first post about C++ lambda with captures as a function pointer was posted. As It was usable for me and other people I made some improvement.
Standard function C pointer api uses void fn(void* data) convention. By default this convention is used and lambda should be declared with a void* argument.
Improved implementation
struct Lambda {
template<typename Tret, typename T>
static Tret lambda_ptr_exec(void* data) {
return (Tret) (*(T*)fn<T>())(data);
}
template<typename Tret = void, typename Tfp = Tret(*)(void*), typename T>
static Tfp ptr(T& t) {
fn<T>(&t);
return (Tfp) lambda_ptr_exec<Tret, T>;
}
template<typename T>
static void* fn(void* new_fn = nullptr) {
static void* fn;
if (new_fn != nullptr)
fn = new_fn;
return fn;
}
};
Exapmle
int a = 100;
auto b = [&](void*) {return ++a;};
Converting lambda with captures to a C pointer
void (*f1)(void*) = Lambda::ptr(b);
f1(nullptr);
printf("%d\n", a); // 101
Can be used this way as well
auto f2 = Lambda::ptr(b);
f2(nullptr);
printf("%d\n", a); // 102
In case return value should be used
int (*f3)(void*) = Lambda::ptr<int>(b);
printf("%d\n", f3(nullptr)); // 103
And in case data is used
auto b2 = [&](void* data) {return *(int*)(data) + a;};
int (*f4)(void*) = Lambda::ptr<int>(b2);
int data = 5;
printf("%d\n", f4(&data)); // 108
Using locally global (static) method it can be done as followed
template <class F>
auto cify_no_args(F&& f) {
static F fn = std::forward<F>(f);
return [] {
return fn();
};
}
Suppose we have
void some_c_func(void (*callback)());
So the usage will be
some_c_func(cify_no_args([&] {
// code
}));
This works because each lambda has an unique signature so making it static is not a problem. Following is a generic wrapper with variadic number of arguments and any return type using the same method.
template <class F>
struct lambda_traits : lambda_traits<decltype(&F::operator())>
{ };
template <typename F, typename R, typename... Args>
struct lambda_traits<R(F::*)(Args...)> : lambda_traits<R(F::*)(Args...) const>
{ };
template <class F, class R, class... Args>
struct lambda_traits<R(F::*)(Args...) const> {
using pointer = typename std::add_pointer<R(Args...)>::type;
static pointer cify(F&& f) {
static F fn = std::forward<F>(f);
return [](Args... args) {
return fn(std::forward<Args>(args)...);
};
}
};
template <class F>
inline typename lambda_traits<F>::pointer cify(F&& f) {
return lambda_traits<F>::cify(std::forward<F>(f));
}
And similar usage
void some_c_func(int (*callback)(some_struct*, float));
some_c_func(cify([&](some_struct* s, float f) {
// making use of "s" and "f"
return 0;
}));
Hehe - quite an old question, but still...
#include <iostream>
#include <vector>
#include <functional>
using namespace std;
// We dont try to outsmart the compiler...
template<typename T>
int ftw(const char *fpath, T callback) {
return callback(fpath);
}
int main()
{
vector<string> entries;
// ... now the #ftw can accept lambda
int ret = ftw("/etc", [&](const char *fpath) -> int {
entries.push_back(fpath);
return 0;
});
// ... and function object too
struct _ {
static int lambda(vector<string>& entries, const char* fpath) {
entries.push_back(fpath);
return 0;
}
};
ret = ftw("/tmp", bind(_::lambda, ref(entries), placeholders::_1));
for (auto entry : entries ) {
cout << entry << endl;
}
return ret;
}
My solution, just use a function pointer to refer to a static lambda.
typedef int (* MYPROC)(int);
void fun(MYPROC m)
{
cout << m(100) << endl;
}
template<class T>
void fun2(T f)
{
cout << f(100) << endl;
}
void useLambdaAsFunPtr()
{
int p = 7;
auto f = [p](int a)->int {return a * p; };
//fun(f);//error
fun2(f);
}
void useLambdaAsFunPtr2()
{
int p = 7;
static auto f = [p](int a)->int {return a * p; };
MYPROC ff = [](int i)->int { return f(i); };
//here, it works!
fun(ff);
}
void test()
{
useLambdaAsFunPtr2();
}
There is a hackish way to convert a capturing lambda into a function pointer, but you need to be careful when using it:
https://codereview.stackexchange.com/questions/79612/c-ifying-a-capturing-lambda
Your code would then look like this (warning: brain compile):
int main()
{
vector<string> entries;
auto const callback = cify<int(*)(const char *, const struct stat*,
int)>([&](const char *fpath, const struct stat *sb,
int typeflag) -> int {
entries.push_back(fpath);
return 0;
});
int ret = ftw("/etc", callback, 1);
for (auto entry : entries ) {
cout << entry << endl;
}
return ret;
}
The answer made by #vladimir-talybin has a little problem:
template <class F>
auto cify_no_args(F&& f) {
static F fn = std::forward<F>(f);
return [] {
return fn();
};
}
That is, if the lambda is called twice in the function, then only the first call is valid, e.g.
// only a demo
void call(std::vector<int>& nums) {
static int i = 0;
cify_no_args([&]() {
nums.emplace_back(i++);
})();
}
int main() {
std::vector<int> nums1, nums2;
call(nums1);
call(nums2);
std::cout << nums1.size() << std::endl << nums2.size() << std::endl;
}
You will show the output of 2 and 0, which means that the second call of call function is using the first call's lambda closure.
That's because the solution is using the static to store the closure's reference, and once the reference is stored, it won't be changed, even for a new closure. Things get worse if the closure will get destructed (due to out of scope or else).
My solution of this problem is simply turning the reference into pointer, and update the pointer's value every time we "construct" the lambda:
template <class F>
auto cify_no_args(F&& f) {
static typename std::remove_reference<F>::type* fn;
fn = &f;
return [] {
return (*fn)();
};
}
The overhead is two more memory access, one for read and one for write, but ensures the correctness.
Found an answer here:
http://meh.schizofreni.co/programming/magic/2013/01/23/function-pointer-from-lambda.html
It converts lambda pointer to void* and convert back when needed.
to void*:
auto voidfunction = new decltype(to_function(lambda))(to_function(lambda));
from void*:
auto function = static_cast< std::function*>(
voidfunction);
I'm trying to create a generic wrapper function that takes a function as a template argument and takes the same arguments as that function as its arguments. For example:
template <typename F, F func>
/* return type of F */ wrapper(Ts... Args /* not sure how to get Ts*/)
{
// do stuff
auto ret = F(std::forward<Ts>(args)...);
// do some other stuff
return ret;
}
The solution needs to be castable to a function pointer with the same type as func so that I can pass it to a C api. In other words, the solution needs to be a function and not a function object. Most importantly, I need to be able to do work in the wrapper function.
If the inline comments aren't clear, I'd like to be able to do something like the following:
struct c_api_interface {
int (*func_a)(int, int);
int (*func_b)(char, char, char);
};
int foo(int a, int b)
{
return a + b;
}
int bar(char a, char b, char c)
{
return a + b * c;
}
c_api_interface my_interface;
my_interface.func_a = wrapper<foo>;
my_interface.func_b = wrapper<bar>;
I looked for related posts and found these, but none of them are quite what I'm trying to do. Most of these posts concern function objects. Is what I'm trying to do even possible?
Function passed as template argument
Function wrapper via (function object) class (variadic) template
How does wrapping a function pointer and function object work in generic code?
How do I get the argument types of a function pointer in a variadic template class?
Generic functor for functions with any argument list
C++ Functors - and their uses
In response to the first 2 responses, I edited the question to make it clear that I need to be able to do work in the wrapper function (i.e. modify some global state before and after the call to the wrapped function)
template<class F, F f> struct wrapper_impl;
template<class R, class... Args, R(*f)(Args...)>
struct wrapper_impl<R(*)(Args...), f> {
static R wrap(Args... args) {
// stuff
return f(args...);
}
};
template<class F, F f>
constexpr auto wrapper = wrapper_impl<F, f>::wrap;
Use as wrapper<decltype(&foo), foo>.
#include <utility>
#include <iostream>
struct c_api_interface { int (*func_a)(int, int); int (*func_b)(char, char, char); };
int foo(int a, int b) { return a + b; }
int bar(char a, char b, char c) { return a + b * c; }
template<typename Fn, Fn fn, typename... Args>
typename std::result_of<Fn(Args...)>::type
wrapper(Args... args) {
std::cout << "and ....it's a wrap ";
return fn(std::forward<Args>(args)...);
}
#define WRAPIT(FUNC) wrapper<decltype(&FUNC), &FUNC>
int main() {
c_api_interface my_interface;
my_interface.func_a = WRAPIT(foo);
my_interface.func_b = WRAPIT(bar);
std:: cout << my_interface.func_a(1,1) << std::endl;
std:: cout << my_interface.func_b('a','b', 1) << std::endl;
return 0;
}
see http://rextester.com/ZZD18334
you may try something like that (Ugly, but works)
#include <iostream>
#include <functional>
struct wrapper_ctx
{
wrapper_ctx ()
{
std::cout << "Before" << std::endl;
}
~wrapper_ctx ()
{
std::cout << "after" << std::endl;
}
};
template <typename F, typename... Args>
auto executor (F&& f, Args&&... args) -> typename std::result_of<F(Args...)>::type
{
wrapper_ctx ctx;
return std::forward<F>(f)( std::forward<Args>(args)...);
}
template <typename F>
class wrapper_helper;
template<typename Ret, typename... Args>
class wrapper_helper <std::function<Ret(Args...)>>
{
std::function<Ret(Args...)> m_f;
public:
wrapper_helper( std::function<Ret(Args...)> f )
: m_f(f) {}
Ret operator()(Args... args) const
{
return executor (m_f, args...);
}
};
template <typename T>
wrapper_helper<T> wrapper (T f)
{
return wrapper_helper <T>(f);
}
int sum(int x, int y)
{
return x + y;
}
int main (int argc, char* argv [])
{
std::function<int(int, int)> f = sum;
auto w = wrapper (f);
std::cout << "Executing the wrapper" << std::endl;
int z = w(3, 4);
std::cout << "z = " << z << std::endl;
}
you probably need something like
template <typename F>
class Wrapper {
public:
Wrapper(F *func) : function(func) {}
operator F* () { return function; }
F *function;
};
Which you can use like void (*funcPtr)(int) = Wrapper<void(int)>(&someFunction);
I think that will be the concise way to do what you want:
template <typename F>
F* wrapper(F* pFunc)
{
return pFunc;
}
and use it like this:
my_interface.func_a = wrapper(foo);
my_interface.func_a(1, 3);
You may try this
template <class R, class... Args>
struct wrap
{
using funct_type = R(*)(Args...);
funct_type func;
wrap(funct_type f): func(f) {};
R operator()(Args&&... args)
{
//before code block
std::cout << "before calling\n";
R ret=func(std::forward<Args>(args)...);
//after code block
std::cout << "After calling\n";
}
};
use like this for example:
int somefunc(double &f, int x);
auto wrapped_somefunc=wrap{somefunc};
double f=1.0;
int x = 2;
auto result=wrapped_somefunc(f,x);
This one is for c++17 and newer uses auto template parameters:
template <auto func, class... Args>
auto wrap_func(Args... args)
{
std::cout << "before calling wrapped func\n";
auto ret = func(args...);
std::cout << "after calling wrapped func\n";
return ret;
}
use for example:
int some_func(int a, int b);
auto ret = wrap_func<some_func>(2, 3);
How can I create a std::function from member function without need for typing std::placeholders::_1, std::placeholders::_2, etc - I would like to "placehold" all arguments, saving only the object itself.
struct Foo{
int bar(int,float,bool) {return 0;}
};
int baz(int,float,bool) {return 0;}
int main() {
Foo object;
std::function<int(int,float,bool)> fun1 = baz; // OK
std::function<int(int,float,bool)> fun2 = std::bind(&Foo::bar, object); // WRONG, needs placeholders
}
I don't want to provide arguments at this stage, I just want to store function + object somewhere. For example I would like to have std::vector with both global functions and member functions. It was easy to do with FastDelegate (fastdelegate::MakeDelegate(object, &Class::function)).
I don't want to use lambda as it would require me to retype arguments as well. I just want old FastDelegate behaviour.
You can use function template which will deduce all member function parameter types, like this:
template<typename Obj, typename Result, typename ...Args>
auto make_delegate(const Obj &x, Result (Obj::*fun)(Args...)) -> // ...
And will return special delegate object, which will contain your object (or pointer to it) and just forward all passed arguments to member function of underlying object:
template<typename Obj, typename Result, typename ...Args>
struct Delegate
{
Obj x;
Result (Obj::*f)(Args...);
template<typename ...Ts>
Result operator()(Ts&&... args)
{
return (x.*f)(forward<Ts>(args)...);
}
};
You will get following usage syntax:
function<int(int,float,bool)> fun = make_delegate(object, &Foo::bar);
Here is full example:
#include <functional>
#include <iostream>
#include <utility>
using namespace std;
struct Foo
{
int bar(int x, float y, bool z)
{
cout << "bar: " << x << " " << y << " " << z << endl;
return 0;
}
};
int baz(int x, float y, bool z)
{
cout << "baz: " << x << " " << y << " " << z << endl;
return 0;
}
template<typename Obj, typename Result, typename ...Args>
struct Delegate
{
Obj x;
Result (Obj::*f)(Args...);
template<typename ...Ts>
Result operator()(Ts&&... args)
{
return (x.*f)(forward<Ts>(args)...);
}
};
template<typename Obj, typename Result, typename ...Args>
auto make_delegate(const Obj &x, Result (Obj::*fun)(Args...))
-> Delegate<Obj, Result, Args...>
{
Delegate<Obj, Result, Args...> result{x, fun};
return result;
}
int main()
{
Foo object;
function<int(int,float,bool)> fun[] =
{
baz,
make_delegate(object, &Foo::bar) // <---- usage
};
for(auto &x : fun)
x(1, 1.0, 1);
}
Output is:
baz: 1 1 1
bar: 1 1 1
Live Demo on Coliru
If you don't want to use placeholders, then std::bind is not for you:
Use lambda:
Foo object;
std::function<int(int,float,bool)> fun = [&object](int a, float b, bool c) {
return object.bar(a,b,c);
};
You can capture object by value if you wish. Perhaps you realize this is no better than using placeholders, as you're typing parameters anyway — in fact you type more in this case!
You can easily do this with variadic generic lambdas in C++14:
template<typename F, typename C>
auto smart_bind(F f, C* c)
{
return [c, f](auto&&... args) { return (c->*f)(std::forward<decltype(args)>(args)...); };
}
// In your code:
std::function<int(int,float,bool)> fun2 = smart_bind(&Foo::bar, &object);
Live demo: https://ideone.com/deR4fy
I was playing with C++ lambdas and their implicit conversion to function pointers. My starting example was using them as callback for the ftw function. This works as expected.
#include <ftw.h>
#include <iostream>
using namespace std;
int main()
{
auto callback = [](const char *fpath, const struct stat *sb,
int typeflag) -> int {
cout << fpath << endl;
return 0;
};
int ret = ftw("/etc", callback, 1);
return ret;
}
After modifying it to use captures:
int main()
{
vector<string> entries;
auto callback = [&](const char *fpath, const struct stat *sb,
int typeflag) -> int {
entries.push_back(fpath);
return 0;
};
int ret = ftw("/etc", callback, 1);
for (auto entry : entries ) {
cout << entry << endl;
}
return ret;
}
I got the compiler error:
error: cannot convert ‘main()::<lambda(const char*, const stat*, int)>’ to ‘__ftw_func_t {aka int (*)(const char*, const stat*, int)}’ for argument ‘2’ to ‘int ftw(const char*, __ftw_func_t, int)’
After some reading. I learned that lambdas using captures can't be implicitly converted to function pointers.
Is there a workaround for this? Does the fact that they can't be "implicitly" converted mean s that they can "explicitly" converted? (I tried casting, without success). What would be a clean way to modify the working example so that I could append the entries to some object using lambdas?.
I just ran into this problem.
The code compiles fine without lambda captures, but there is a type conversion error with lambda capture.
Solution with C++11 is to use std::function (edit: another solution that doesn't require modifying the function signature is shown after this example). You can also use boost::function (which actually runs significantly faster). Example code - changed so that it would compile, compiled with gcc 4.7.1:
#include <iostream>
#include <vector>
#include <functional>
using namespace std;
int ftw(const char *fpath, std::function<int (const char *path)> callback) {
return callback(fpath);
}
int main()
{
vector<string> entries;
std::function<int (const char *fpath)> callback = [&](const char *fpath) -> int {
entries.push_back(fpath);
return 0;
};
int ret = ftw("/etc", callback);
for (auto entry : entries ) {
cout << entry << endl;
}
return ret;
}
Edit:
I had to revisit this when I ran into legacy code where I couldn't modify the original function signature, but still needed to use lambdas. A solution that doesn't require modifying the function signature of the original function is below:
#include <iostream>
#include <vector>
#include <functional>
using namespace std;
// Original ftw function taking raw function pointer that cannot be modified
int ftw(const char *fpath, int(*callback)(const char *path)) {
return callback(fpath);
}
static std::function<int(const char*path)> ftw_callback_function;
static int ftw_callback_helper(const char *path) {
return ftw_callback_function(path);
}
// ftw overload accepting lambda function
static int ftw(const char *fpath, std::function<int(const char *path)> callback) {
ftw_callback_function = callback;
return ftw(fpath, ftw_callback_helper);
}
int main() {
vector<string> entries;
std::function<int (const char *fpath)> callback = [&](const char *fpath) -> int {
entries.push_back(fpath);
return 0;
};
int ret = ftw("/etc", callback);
for (auto entry : entries ) {
cout << entry << endl;
}
return ret;
}
Since capturing lambdas need to preserve a state, there isn't really a simple "workaround", since they are not just ordinary functions. The point about a function pointer is that it points to a single, global function, and this information has no room for a state.
The closest workaround (that essentially discards the statefulness) is to provide some type of global variable which is accessed from your lambda/function. For example, you could make a traditional functor object and give it a static member function which refers to some unique (global/static) instance.
But that's sort of defeating the entire purpose of capturing lambdas.
ORIGINAL
Lambda functions are very convenient and reduce a code. In my case I needed lambdas for parallel programming. But it requires capturing and function pointers. My solution is here. But be careful with scope of variables which you captured.
template<typename Tret, typename T>
Tret lambda_ptr_exec(T* v) {
return (Tret) (*v)();
}
template<typename Tret = void, typename Tfp = Tret(*)(void*), typename T>
Tfp lambda_ptr(T& v) {
return (Tfp) lambda_ptr_exec<Tret, T>;
}
Example
int a = 100;
auto b = [&]() { a += 1;};
void (*fp)(void*) = lambda_ptr(b);
fp(&b);
Example with a return value
int a = 100;
auto b = [&]() {return a;};
int (*fp)(void*) = lambda_ptr<int>(b);
fp(&b);
UPDATE
Improved version
It was a while since first post about C++ lambda with captures as a function pointer was posted. As It was usable for me and other people I made some improvement.
Standard function C pointer api uses void fn(void* data) convention. By default this convention is used and lambda should be declared with a void* argument.
Improved implementation
struct Lambda {
template<typename Tret, typename T>
static Tret lambda_ptr_exec(void* data) {
return (Tret) (*(T*)fn<T>())(data);
}
template<typename Tret = void, typename Tfp = Tret(*)(void*), typename T>
static Tfp ptr(T& t) {
fn<T>(&t);
return (Tfp) lambda_ptr_exec<Tret, T>;
}
template<typename T>
static void* fn(void* new_fn = nullptr) {
static void* fn;
if (new_fn != nullptr)
fn = new_fn;
return fn;
}
};
Exapmle
int a = 100;
auto b = [&](void*) {return ++a;};
Converting lambda with captures to a C pointer
void (*f1)(void*) = Lambda::ptr(b);
f1(nullptr);
printf("%d\n", a); // 101
Can be used this way as well
auto f2 = Lambda::ptr(b);
f2(nullptr);
printf("%d\n", a); // 102
In case return value should be used
int (*f3)(void*) = Lambda::ptr<int>(b);
printf("%d\n", f3(nullptr)); // 103
And in case data is used
auto b2 = [&](void* data) {return *(int*)(data) + a;};
int (*f4)(void*) = Lambda::ptr<int>(b2);
int data = 5;
printf("%d\n", f4(&data)); // 108
Using locally global (static) method it can be done as followed
template <class F>
auto cify_no_args(F&& f) {
static F fn = std::forward<F>(f);
return [] {
return fn();
};
}
Suppose we have
void some_c_func(void (*callback)());
So the usage will be
some_c_func(cify_no_args([&] {
// code
}));
This works because each lambda has an unique signature so making it static is not a problem. Following is a generic wrapper with variadic number of arguments and any return type using the same method.
template <class F>
struct lambda_traits : lambda_traits<decltype(&F::operator())>
{ };
template <typename F, typename R, typename... Args>
struct lambda_traits<R(F::*)(Args...)> : lambda_traits<R(F::*)(Args...) const>
{ };
template <class F, class R, class... Args>
struct lambda_traits<R(F::*)(Args...) const> {
using pointer = typename std::add_pointer<R(Args...)>::type;
static pointer cify(F&& f) {
static F fn = std::forward<F>(f);
return [](Args... args) {
return fn(std::forward<Args>(args)...);
};
}
};
template <class F>
inline typename lambda_traits<F>::pointer cify(F&& f) {
return lambda_traits<F>::cify(std::forward<F>(f));
}
And similar usage
void some_c_func(int (*callback)(some_struct*, float));
some_c_func(cify([&](some_struct* s, float f) {
// making use of "s" and "f"
return 0;
}));
Hehe - quite an old question, but still...
#include <iostream>
#include <vector>
#include <functional>
using namespace std;
// We dont try to outsmart the compiler...
template<typename T>
int ftw(const char *fpath, T callback) {
return callback(fpath);
}
int main()
{
vector<string> entries;
// ... now the #ftw can accept lambda
int ret = ftw("/etc", [&](const char *fpath) -> int {
entries.push_back(fpath);
return 0;
});
// ... and function object too
struct _ {
static int lambda(vector<string>& entries, const char* fpath) {
entries.push_back(fpath);
return 0;
}
};
ret = ftw("/tmp", bind(_::lambda, ref(entries), placeholders::_1));
for (auto entry : entries ) {
cout << entry << endl;
}
return ret;
}
My solution, just use a function pointer to refer to a static lambda.
typedef int (* MYPROC)(int);
void fun(MYPROC m)
{
cout << m(100) << endl;
}
template<class T>
void fun2(T f)
{
cout << f(100) << endl;
}
void useLambdaAsFunPtr()
{
int p = 7;
auto f = [p](int a)->int {return a * p; };
//fun(f);//error
fun2(f);
}
void useLambdaAsFunPtr2()
{
int p = 7;
static auto f = [p](int a)->int {return a * p; };
MYPROC ff = [](int i)->int { return f(i); };
//here, it works!
fun(ff);
}
void test()
{
useLambdaAsFunPtr2();
}
There is a hackish way to convert a capturing lambda into a function pointer, but you need to be careful when using it:
https://codereview.stackexchange.com/questions/79612/c-ifying-a-capturing-lambda
Your code would then look like this (warning: brain compile):
int main()
{
vector<string> entries;
auto const callback = cify<int(*)(const char *, const struct stat*,
int)>([&](const char *fpath, const struct stat *sb,
int typeflag) -> int {
entries.push_back(fpath);
return 0;
});
int ret = ftw("/etc", callback, 1);
for (auto entry : entries ) {
cout << entry << endl;
}
return ret;
}
The answer made by #vladimir-talybin has a little problem:
template <class F>
auto cify_no_args(F&& f) {
static F fn = std::forward<F>(f);
return [] {
return fn();
};
}
That is, if the lambda is called twice in the function, then only the first call is valid, e.g.
// only a demo
void call(std::vector<int>& nums) {
static int i = 0;
cify_no_args([&]() {
nums.emplace_back(i++);
})();
}
int main() {
std::vector<int> nums1, nums2;
call(nums1);
call(nums2);
std::cout << nums1.size() << std::endl << nums2.size() << std::endl;
}
You will show the output of 2 and 0, which means that the second call of call function is using the first call's lambda closure.
That's because the solution is using the static to store the closure's reference, and once the reference is stored, it won't be changed, even for a new closure. Things get worse if the closure will get destructed (due to out of scope or else).
My solution of this problem is simply turning the reference into pointer, and update the pointer's value every time we "construct" the lambda:
template <class F>
auto cify_no_args(F&& f) {
static typename std::remove_reference<F>::type* fn;
fn = &f;
return [] {
return (*fn)();
};
}
The overhead is two more memory access, one for read and one for write, but ensures the correctness.
Found an answer here:
http://meh.schizofreni.co/programming/magic/2013/01/23/function-pointer-from-lambda.html
It converts lambda pointer to void* and convert back when needed.
to void*:
auto voidfunction = new decltype(to_function(lambda))(to_function(lambda));
from void*:
auto function = static_cast< std::function*>(
voidfunction);