-
Notifications
You must be signed in to change notification settings - Fork 4
/
std_mem_fn_impl.cpp
82 lines (65 loc) · 1.84 KB
/
std_mem_fn_impl.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
// A basic implementation of std::mem_fn
#include <functional>
#include <iostream>
struct Foo {
int _m;
Foo(int m) : _m(m) {}
int get() const {
std::cout << "void Foo::get() const" << std::endl;
return _m;
}
void add(int m) {
std::cout << "int Foo::add()" << std::endl;
_m += m;
}
};
template <typename PTR>
class Wrapper {
PTR _ptr; // pointer to member function
public:
Wrapper(PTR ptr) : _ptr(ptr) {}
template <typename T, typename... Args>
void operator()(T& obj, Args&&... args) const {
(obj.*_ptr)(std::forward<Args>(args)...);
}
template <typename T, typename... Args>
void operator()(const T& obj, Args&&... args) const {
(obj.*_ptr)(std::forward<Args>(args)...);
}
template <typename T, typename... Args>
void operator()(T&& obj, Args&&... args) const {
(obj.*_ptr)(std::forward<Args>(args)...);
}
template <typename T, typename... Args>
void operator()(T* obj, Args&&... args) const {
(obj->*_ptr)(std::forward<Args>(args)...);
}
template <typename T, typename... Args>
void operator()(const T* obj, Args&&... args) const {
(obj->*_ptr)(std::forward<Args>(args)...);
}
};
template <class PTR>
auto my_mem_fn(PTR ptr) {
return Wrapper<PTR>{ptr};
}
int main() {
Foo foo(42);
const Foo cfoo(42);
Foo* pFoo = new Foo(42);
const Foo* cpFoo = new Foo(42);
auto memfn1 = my_mem_fn(&Foo::get);
auto memfn2 = my_mem_fn(&Foo::add);
memfn1(foo);
memfn1(cfoo);
memfn1(pFoo);
memfn1(cpFoo);
memfn1(Foo{42}); // works with rvalues also
memfn2(foo, 10);
memfn2(pFoo, 10);
memfn2(Foo{42}, 10); // works with rvalues also
// memfn2(cfoo, 10); // const violation
// memfn2(cpFoo, 10); // const violation
delete pFoo;
delete cpFoo;
}