-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfunction.cpp
More file actions
58 lines (45 loc) · 1.28 KB
/
function.cpp
File metadata and controls
58 lines (45 loc) · 1.28 KB
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
#include <iostream>
#include <memory>
#include <functional>
template<typename T>
struct function;
template<typename R, typename ...Args>
struct function<R(Args...)> {
template<typename FunctionObject>
function(FunctionObject fo) : callable(std::make_unique<callable_impl<FunctionObject>>(fo)) {}
R operator()(Args... args) {
return callable->call(args...);
};
private:
struct callable_interface {
virtual R call(Args...) = 0;
virtual ~callable_interface() = default;
};
template<typename Callback>
struct callable_impl : callable_interface {
Callback callback;
callable_impl(Callback callback_) : callback(std::move(callback_)) {}
R call(Args ...args) {
return std::invoke(callback, args...); }
};
std::unique_ptr<callable_interface> callable;
};
int f(int x, int y) {
return x + y;
}
struct A {
int f(int x, int y) {
return 100 * x * y;
}
};
int main() {
// function<int> f1; -> uncomment should throw error
function<int(int,int)> f2(f);
function<int(int,int)> f3([](int a, int b){return a * b;});
function<int(A&,int,int)> f4(&A::f);
assert(f2(1, 2) == 3);
assert(f3(2, 3) == 6);
A a;
assert(f4(a, 2, 3) == 600);
return 0;
}