ifndef FUNCTION_H define FUNCTION_H template typename typename class A

 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
#ifndef FUNCTION_H
#define FUNCTION_H
template<typename A, typename R>
class AbstractFunction
{
protected:
public:
virtual R operator()(A param) const {};
};
#include <memory>
using namespace std;
template<typename Z, typename X, typename Y>
class Composition : public AbstractFunction<Z, Y>
{ //g*f, f: A-> B, g: B->R
const AbstractFunction<Z, X>* f;
const AbstractFunction<X, Y>* g;
public:
Composition(const AbstractFunction<X, Y>& _g, const AbstractFunction<Z, X>& _f)
{
f = &_f;
g = &_g;
}
Y operator()(Z param) const {
return (*g)((*f)(param));
}
};
template <typename X, typename Y, typename Z>
Composition<Z, X, Y> operator*(const AbstractFunction<X, Y> &g, // Z -> X -> Y
const AbstractFunction<Z, X> &f)
{
return Composition<Z, X, Y>(g, f);
}
template<typename X, typename Y, typename Func>
class Function : public AbstractFunction<X, Y>
{
public:
Func func;
Function(Func function): func(function) {}
Y operator()(X param) const { return func(param); }
};
//valgrind ~/C++/lab11-18_Function-Debug/lab11-18_Function
#endif // FUNCTION_H
#include <iostream>
int f(char s) {return s / 2;}
long g(int k) {return k * 5;}
long m(long v) {return v * 6;}
int main()
{
Function<char, int, int(*)(char)> k(f);
Function<int, long, long(*)(int)> d(g);
Function<long, long, long(*)(long)> z(m);
cout << k(2) << " " << d(10) << endl;
//Composition<char, int, long> comp(g, f); //char->int->long, g(f)
cout << (z * (z * (d * k)))(10) << endl;
return 0;
}