Skip to content

Instantly share code, notes, and snippets.

@clee704
Created September 2, 2016 08:56
Show Gist options
  • Save clee704/d02493e1790bd67d3cf0dc21b07c8b73 to your computer and use it in GitHub Desktop.
Save clee704/d02493e1790bd67d3cf0dc21b07c8b73 to your computer and use it in GitHub Desktop.
Make a unary lambda function from a pointer to function/data member (C++14)
#include <functional>
#include <iostream>
#include <utility>
using namespace std;
template<class>
struct memfun_traits {};
template<class C, class R, class... Args>
struct memfun_traits<R (C::*)(Args...)> {
typedef C class_type;
typedef R return_type;
};
template<class C, class R, class... Args>
struct memfun_traits<R (C::*)(Args...) const> {
typedef C class_type;
typedef R return_type;
};
template<class>
struct memdat_traits {};
template<class C, class T>
struct memdat_traits<T C::*> {
typedef C class_type;
typedef T data_type;
};
template<class MemFun>
auto make_lambda_f(MemFun pf) {
return [pf] (typename memfun_traits<MemFun>::class_type x) { return (x.*pf)(); };
}
template<class MemDat>
auto make_lambda_d(MemDat pd) {
return [pd] (typename memdat_traits<MemDat>::class_type x) { return x.*pd; };
}
template<class T, class Func>
typename result_of<Func(T)>::type
do_something(T x, Func f) {
return f(x);
}
struct P : public pair<int, int> {
using pair<int, int>::pair;
int get_first() const { return first; }
int get_second() const { return second; }
};
int func(P x) { return x.second; }
int main() {
P x(13, 42);
cout << do_something(x, func) << endl;
cout << do_something(x, [] (P x) { return x.second; }) << endl;
cout << do_something(x, make_lambda_d(&P::first)) << endl;
cout << do_something(x, make_lambda_d(&P::second)) << endl;
cout << do_something(x, make_lambda_f(&P::get_first)) << endl;
cout << do_something(x, make_lambda_f(&P::get_second)) << endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment