前期回顾 $$ 程序 = 算法 + 数据结构 $$
数据结构: 能够存储任意类型
算 法: 能够操作存储任意类型数据的数据结构
泛型编程
泛型编程
面向过程编程
用 模板 实现函数过程
面向对象编程
用 模板 实现类
抽象化:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #include <iostream> using namespace std ;int f (int x) { return x * 2 + 1 ; } int main () { cout << 1 * 2 + 1 ; cout << f(1 ); cout << f(2 ); cout << f(3 ); cout << f(4 ); return 0 ; }
模板 将【任意类型】从程序设计 中抽象出来
模板 模板函数 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 #include <iostream> using namespace std ;#define BEGINS(x) namespace x{ #define ENDS(x) } BEGINS(test1) template <typename T>T add (T a, T b) { return a + b; } cout << " add(3, 4) = " << add(3 , 4 ) << endl ; return 0 ; } ENDS(test1) int main () { test1::main(); return 0 ; }
查看模板实例化后的方法
查看可执行程序中的若干个符号的定义
当我们在使用模板方法的时候,使用其实不是模板方法而是模板生成的那一段具体的代码
add(3, 4) 调用形式
为什么编译器它会实例话出来 $add$就是通过调用形式完成的模板类型自动推到,看3是什么类型在看4是什么类型(int),这个时候模板当中那个参数推到是不存在冲突的
这时候才会生成一个$add$
1 2 3 4 5 6 int main () { cout << " add(3, 4) = " << add(3 , 4 ) << endl ; cout << "add(3.1, 4.2) = " << add(3.1 , 4.2 ) << endl ; return 0 ; }
模板函数-代码合集
decltype: 根基表达式推导类型(不进行表达式计算, 不进行表示执行,不执行但是也保证这段代码是不违法的)
auto(可以在声明变量的时候根据变量初始值的类型自动推到) + decltype 返回值后置
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 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 #include <iostream> using namespace std ;#define BEGINS(x) namespace x{ #define ENDS(x) } BEGINS(test1) template <typename T>T add (T a, T b) { return a + b; } int main () { cout << " add(3, 4) = " << add(3 , 4 ) << endl ; cout << "add(3.1, 4.2) = " << add(3.1 , 4.2 ) << endl ; cout << "add(3, 4.2) = " << add<double >(3 , 4.2 ) << endl ; return 0 ; } ENDS(test1) BEGINS(test2) class A {public : A() = delete ; A(int x) : x(x) {} int x; }; class B {public : B() = delete ; B(int x) : x(x) {} int x; }; class C {public : C() = delete ; C(int x): x(x) {} int x; }; C operator +(const A &a, const B &b) { return C(a.x + b.x); } C operator +(const B &a, const A &b) { return C(a.x + b.x); } ostream &operator <<(ostream &out , const C &c) { out << "Class C.x = " << c.x; return out; } template <typename T, typename U>auto add(T a, U b) -> decltype(a + b) { return a + b; } template <typename T>void judge (T a) { cout << "unknow type" << endl ; return ; } template <>void judge (int a) { cout << "int type" << endl ; return ; } template <>void judge (double a) { cout << "double type" << endl ; } int main () { cout << " add(3, 4) = " << add(3 , 4 ) << endl ; cout << "add(3.1, 4.2) = " << add(3.1 , 4.2 ) << endl ; cout << "add(3, 4.2) = " << add<double >(3 , 4.2 ) << endl ; cout << "add(3, 4.2) = " << add(3 , 4.2 ) << endl ; A a (56 ) ; B b (78 ) ; cout << "add(A, B) = " << add(a, b) << endl ; do { decltype (3 + 4.2 ) a; decltype (4.2 + 3 ) b; decltype (3 + 4 ) c; decltype (string ("abc" ) + string ("def" )) d; judge(a), judge(b), judge(c), judge(d); } while (0 ); return 0 ; } ENDS(test2) int main () { test2::main(); return 0 ; }
模板类 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 BEGINS(test3) template <typename T>class PrintAnt {public : PrintAnt(ostream &out) : out(out) {} PrintAnt &Print (T a) { out << a; return *this ; } PrintAnt &endl () { out << std ::endl ; return *this ; } private : ostream &out; }; int main () { PrintAnt<int > pint (cout ) ; PrintAnt<double > pdouble (cout ) ; PrintAnt<string > pstring (cout ) ; pint.Print(3 ).endl (); pdouble.Print(3.3 ).endl (); pstring.Print("hello world" ).endl (); return 0 ; } ENDS(test3) BEGINS(test4) class PrintAnt {public : PrintAnt(ostream &out) : out(out) {} template <typename T> PrintAnt &Print (T a) { out << a; return *this ; } PrintAnt &endl () { out << std ::endl ; return *this ; } private : ostream &out; }; int mian () { PrintAnt p (cout ) ; p.Print(3 ).endl ().Print(3.3 ).endl ().Print("hello world" ).endl (); return 0 ; } ENDS(test4) int main () { test4::mian(); return 0 ; }
左值、右值、移动构造
常态
临时
值:
左值
右值
引用:
左值引用
右值引用
这是四个概念
如果一个值是左值话那么它将优先绑定函数的佐值引用版本
如果一个值是右值话那么它将优先绑定函数的右值引用版本
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 #include <iostream> using namespace std ;#define BEGINS(x) namespace x { #define ENDS(x) } BEGINS(test1) void judge2 (int &x) { cout << "(left value - 2) : " ; return ; } void judge2 (int &&x) { cout << "(right valie - 2) : " ; } void judge (int &x) { judge2(x); cout << "left value" << endl ; return ; } void judge (int &&x) { judge2(forward<int &&>(x)); cout << "right valie" << endl ; } #define TEST(a) { \ cout << "judge " << #a << " : " ; \ judge(a); \ } int main () { int n = 123 ; (n += 2 ) = 100 ; cout << n << endl ; TEST(n); TEST(n + 1 ); TEST(n++); TEST(++n); TEST(1 + 2 ); TEST(n += 2 ); return 0 ; } ENDS(test1) int main () { test1::main(); return 0 ; }
怎么判断是不是左值:
最简单的判断依据就是当前表达式能不能放到运算符的左面,如果一个表达式能放到赋值运算符的左面那么他就是一个左值
左值表常态、右值表临时
左值:
当代码到了下一行的时候,我们上一行的表达的值我是否还能通过单一变量访问道
列:
int n = 123;
n += 2;
可以用过 n 访问到(左值表常态)
int n = 123;
n + 1;
因为(n + 1)会存储在一个临时变量上的,所以它是一个右值因为(右值表临时)
左值:-> 返回引用
右值:-> 返回值
运算符重载返回左值右值 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 #include <iostream> using namespace std ;#define BEGINS(x) namespace x { #define ENDS(x) } BEGINS(test2) class Point ;void judge (Point &x) { cout << "left value" << endl ; return ; } void judge (Point &&x) { cout << "right valie" << endl ; } #define TEST(a) { \ cout << "judge " << #a << " : " ; \ judge(a); \ } class Point {public : Point(int x = 0 , int y = 0 ) : __x(x), __y(y) {} int x () { return __x; } int y () { return __y; } Point &operator +=(int d) { __x += d; __y += d; return *this ; } Point operator +(int d) { return Point(__x + d, __y + d); } private : int __x, __y; }; int main () { Point p (3 , 4 ) ; TEST(p); TEST(p += 1 ); TEST(p + 1 ); return 0 ; } ENDS(test2) int main () { test2::main(); return 0 ; }
右值->移动构造 移动构造相当于
一个师傅一个徒弟,那么师傅要四了说要把把毕生绝学都传给徒弟那么传给徒弟两种方式
嘴述,完了徒弟自己去练(相当于深拷贝)、(效率底)、(O(n))
直接内力传送完,师傅也就挂掉了一身功力就全都传给徒弟了师傅就什么都没有了(相当于右值直接移动构造)、(效率很高)、(O(1))
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 83 84 #include <iostream> using namespace std ;#define BEGINS(x) namespace x { #define ENDS(x) } BEGINS(test3) class Array {public : Array(int n = 5 ) :__size(n), data(new int [n]) { cout << this << " : default constructor" << endl ; } Array(const Array &a) : __size(a.__size), data(new int [__size]) { for (int i = 0 ; i < __size; i++) { new (data + i) int (a[i]); } cout << this << " : deep copy constructor" << endl ; return ; } Array(Array &&a) : __size(a.__size), data(a.data) { a.data = nullptr ; a.__size = 0 ; cout << "move constructor " << endl ; return ; } int size () { return __size; } int &operator [](int ind) const { return data[ind]; } Array operator +(Array &a) { Array ret (__size + a.__size) ; for (int i = 0 ; i < __size; i++) { ret[i] = data[i]; } for (int i = __size; i < ret.size(); i++) { ret[i] = a.data[i - __size]; } return ret; } ~Array() { cout << this << " : destructor" << endl ; delete [] data; return ; } private : int __size, *data; }; int main () { Array a, b; Array c = a + b; Array d (move(a)) ; return 0 ; } ENDS(test3) int main () { test3::main(); return 0 ; }
模板的特化、偏特化 类模板:特化 (全特化)、偏特化
函数模板:特化 (全特化)
特化:就好比机场的VIP通道给少数人准备
模板(全特化): 所以的参水都被固定了
有template关键字就是一个模板
模板的特化、偏特化-代码实现
test1-函数模板、(特化)全特化
test2-模板类模板、(特化)全特化、偏特化
test3-((特化)全特化、偏特化)实现判断相关的类型有没有构造函数
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 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 #include <iostream> using namespace std ;#define BEGINS(x) namespace x { #define ENDS(x) } BEGINS(test1) template <typename T>T add (T a, T b) { return a + b; } template <>int add (int a, int b) { cout << "int template" << endl ; return a + b; } int main () { cout << add(3 , 4 ) << endl ; cout << add(3.1 , 4.1 ) << endl ; return 0 ; } ENDS(test1) BEGINS(test2) template <typename T, typename U>class Test {public : Test() { cout << "normal template<T, U> " << endl ; } }; template <>class Test <int , double > {public : Test() { cout << "specialization template<int, double> " << endl ; } }; template <typename T>class Test <int , T> {public : Test() { cout << "partial specialization template<int, T> " << endl ; } }; int main () { Test<string , int > t1; Test<int , double > t2; Test<int , string > t3; return 0 ; } ENDS(test2) BEGINS(test3) class A { };class B { };class yes_constructor {public : static const char *has_constructor; }; const char *yes_constructor::has_constructor = "yes" ;class no_constructor {public : static const char *has_constructor; }; const char *no_constructor::has_constructor = "no" ;template <typename T>class type_trais : public yes_constructor {};template <typename T>class type_trais < T *> : public no_constructor{};template <>class type_trais <int > : public no_constructor{};template <>class type_trais <double > : public no_constructor {};#define TEST(type) \ cout << #type << " : "<< type_trais<type>::has_constructor << endl; int main () { TEST(int ); TEST(A); TEST(double ); TEST(B); TEST(string ); TEST(string *); return 0 ; } #undef TEST ENDS(test3) BEGINS(test4) class A { };class B { };class yes_constructor { };class no_constructor { };template <typename T>class type_trais {public : typedef yes_constructor has_constructor; }; template <typename T>class type_trais < T *> {public : typedef no_constructor has_constructor; }; template <>class type_trais <int > {public : typedef no_constructor has_constructor; }; template <>class type_trais <double > {public : typedef no_constructor has_constructor; }; ostream &operator <<(ostream &out, const no_constructor &) { out << "yes" ; return out; } ostream &operator <<(ostream &out, const yes_constructor &) { out << "no" ; return out; } #define TEST(type) \ cout << #type << " : "<< type_trais<type>::has_constructor() << endl; int main () { TEST(int ); TEST(A); TEST(double ); TEST(B); TEST(string ); TEST(string *); return 0 ; } ENDS(test4) int main () { test4::main(); return 0 ; }
可变参数模板 1 2 3 4 5 6 7 template <typename T, typename ...ARGS>void Print (const T &a, ARGS... args) { cout << a << endl ; Print(args...); return ; }
代码解释:
**ARGS(类型集合)**代表模板中剩余部分的类型数量是可变的,但最少为1个。
此代码会递归展开模板函数Print
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> using namespace std ;#define BEGINS(x) namespace x { #define ENDS(x) } BEGINS(test1) class A {public : A(int x, int y) : x(x), y(y) {} int x, y; }; ostream &operator <<(ostream &out, const A &a) { out << "Class A : " << a.x << ", " << a.y; return out; } template <typename T>void Print (T a) { cout << a << endl ; return ; } template <typename T, typename ...ARGS>void Print (T a, ARGS... args) { cout << a << " | " ; Print(args...); return ; } int main () { A a (5 , 6 ) ; Print("hello world" ); Print("hello world" , 3 , 3.4 , a); Print(3 , a, 6.1 , "ttw" ); return 0 ; } ENDS(test1) int main () { test1::main(); return 0 ; }
代码合集
test1::打印任意参数
test2::分析变参模板的参数
test3::可变参数扩充实现智能传入3个参数
test4::可变参数扩充 类似function
test5::编译期常量
test6::变参模板
1 2 3 4 5 6 // 打印任意参数 // test1::main(); // 分析变参模板的参数 // test2::main(); // function // test4::mian();
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 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 BEGINS(test2) template <typename T, typename ... ARGS>class ARG {public : typedef T type; typedef ARG<ARGS...> rest; }; template <typename T>class ARG < T> {public : typedef T type; }; template <typename T, typename ...ARGS>class Test {public : T operator () (typename ARG<ARGS...>::type a, typename ARG<ARGS...>::rest::type b) { return a + b; } }; int main () { Test<int , int , int > t1; Test<double , double , int > t2; cout << t1(3 , 4 ) << endl ; cout << t2(3.5 , 4 ) << endl ; return 0 ; } ENDS(test2) BEGINS(test3) template <typename T, typename ... ARGS>class ARG {public : typedef T type; typedef ARG<ARGS...> rest; }; template <typename T>class ARG < T> {public : typedef T type; typedef T ftype; }; template <typename T, typename ...ARGS>class Test {public : T operator () (typename ARG<ARGS...>::type a, typename ARG<ARGS...>::rest::ftype b) { return a + b; } }; int main () { Test<int , int , int > t1; Test<double , double , int > t2; cout << t1(3 , 4 ) << endl ; cout << t2(3.5 , 4 ) << endl ; return 0 ; } ENDS(test3) BEGINS(test4) template <typename T, typename ... ARGS>class ARG {public : typedef T type; typedef ARG<ARGS...> rest; }; template <typename T>class ARG < T> {public : typedef T type; typedef T ftype; }; template <typename T, typename ...ARGS> class Test ;template <typename T, typename ...ARGS>class Test < T(ARGS...)> {public : T operator () (typename ARG<ARGS...>::type a, typename ARG<ARGS...>::rest::ftype b) { return a + b; } }; int main () { Test<int (int , int )> t1; Test<double (int , int )> t2; cout << t1(3 , 4 ) << endl ; cout << t2(3.5 , 4 ) << endl ; return 0 ; } ENDS(test4) BEGINS(test5) template <int M>void Print () { cout << M << ", " ; Print<M - 1 >(); } template <>void Print<1 >() { cout << 1 << endl ; return ; } int main () { Print<5 >(); Print<15 >(); Print<2 >(); Print<10 >(); return 0 ; } ENDS(test5) BEGINS(test6) template <int N, typename T, typename ...ARGS>struct ARG { typedef typename ARG<N - 1 , ARGS...>::type type; }; template <typename T, typename ...ARGS>struct ARG <1 , T, ARGS...> { typedef T type; }; template <typename T>struct ARG <1 , T> { typedef T type; }; template <typename T, typename ...ARGS>struct NUM_ARGS { static constexpr int r = NUM_ARGS<ARGS...>::r + 1 ; }; template <typename T>struct NUM_ARGS < T> { static constexpr int r = 1 ; }; template <int N>struct Zero { typedef int no; }; template <>struct Zero <0 > { typedef int yes; }; template <typename T, typename ...ARGS> class Test ;template <typename T, typename ...ARGS>class Test < T(ARGS...)> {public : typedef typename Zero<2 - NUM_ARGS<ARGS...>::r>::yes TYPE_NUM_2; T operator () ( typename ARG<1 , ARGS...>::type a, typename ARG<2 , ARGS...>::type b) { return a + b; } }; int main () { Test<int (int , int )> t1; cout << t1(3 , 2 ); return 0 ; } ENDS(test6) int main () { test6::main(); return 0 ; }
模板练习-代码
test1::实现一个模板进行累加求和
test2::判断一个数字是不是偶数
test3::判断一个数字的范围
test4::判断一个数字是不是素数
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 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 #include <iostream> using namespace std ;#define BEGINS(x) namespace x { #define ENDS(x) } BEGINS(test1) template <int n>class sum {public : static constexpr int r = sum<n - 1 >::r + n; }; template <>class sum <1 > {public : static constexpr int r = 1 ; }; int main () { cout << sum<5 >::r << endl ; cout << sum<7 >::r << endl ; cout << sum<100 >::r << endl ; return 0 ; } ENDS(test1) BEGINS(test2) template <int N>struct YES_OR_NO { static const char *r; }; template <int N>const char *YES_OR_NO<N>::r = "no" ;template <>const char *YES_OR_NO<0 >::r = "yes" ;template <int n>class is_even {public : static const char *r; }; template <int N>const char *is_even<N>::r = YES_OR_NO<N % 2 >::r;int main () { cout << is_even<5 >::r << endl ; cout << is_even<6 >::r << endl ; return 0 ; } ENDS(test2) BEGINS(test3) template <int n>class score_judge {public : static constexpr const char *r = ( n>= 60 ) ? "good" : "bad" ; }; int main () { cout << score_judge<60 >::r << endl ; cout << score_judge<54 >::r << endl ; return 0 ; } ENDS(test3) BEGINS(test4) template <int i, int N>class getNext {public : static constexpr int r = (N % i ? i + 1 : 0 ); }; template <int i, int N>class test {public : static constexpr const char *r = ((i * i) > N ? "yes" : test<getNext<i, N>::r, N>::r); }; template <int N>class test <0 , N> {public : static constexpr const char *r = "no" ; }; template <int N>class is_prime {public : static constexpr const char *r = test<2 , N>::r; }; int main () { cout << "2 : " << is_prime<2 >::r << endl ; cout << "3 : " << is_prime<3 >::r << endl ; cout << "4 : " << is_prime<5 >::r << endl ; cout << "8 : " << is_prime<8 >::r << endl ; cout << "103 : " << is_prime<103 >::r << endl ; return 0 ; } ENDS(test4) int main () { test1::main(); cout << "---------------- 分割线 -------------------" << endl ; test2::main(); cout << "---------------- 分割线 -------------------" << endl ; test3::main(); cout << "---------------- 分割线 -------------------" << endl ; test4::main(); return 0 ; }
模板引用 引用折叠
再模板中如果是奇数
个就是左值引用
,偶数个是右值引用
// 模板中接收的是一个引用是&&
, 而不是传统意义上右值引用
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 #include <iostream> using namespace std ;#define BEGINS(x) namespace x { #define ENDS(x) } template <typename T>BEGINS(reference_param) template <typename T>struct remove_reference { typedef T type; }; template <typename T>struct remove_reference < T &> { typedef T type; }; template <typename T>struct remove_reference < T &&> { typedef T type; }; template <typename T>void func (T &&a) { typename remove_reference<T>::type c; cout << "function T& a = " << a << endl ; return ; } int main () { int n = 123 ; func(n); func(123 ); typename remove_reference<int &&>::type a; typename remove_reference<int &>::type b; typename remove_reference<int >::type c; return 0 ; } ENDS(reference_param)
代码合集-function(手动实现)
reference_param::去掉&
bind_usage::bind 方法 将函数和相关的参数打包绑定
addConst::添加const限定
addLvalueReference::转换成左值引用
removePointer::去掉 *
function_impl::function_手动实现
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 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 #include <iostream> #include <functional> using namespace std ;#define BEGINS(x) namespace x { #define ENDS(x) } BEGINS(function_impl) template <typename T, typename ...ARGS>class Base {public : virtual T run (ARGS...) = 0 ; virtual Base<T, ARGS...> *getCopy() = 0; virtual ~Base(){} }; template <typename T, typename ...ARGS>class normal_function : public Base<T, ARGS...> {public : normal_function(T(*ptr)(ARGS...)) : func(ptr) {} T run (ARGS... args) override { return func(forward<ARGS>(args)...); } Base<T, ARGS...> *getCopy() override { return new normal_function(*this ); } private : T (*func)(ARGS...); }; template <typename CLASS_T, typename T, typename ...ARGS>class functor : public Base<T, ARGS...> {public : functor(CLASS_T obj) : obj(obj) {} T run (ARGS... args) override { return obj(forward<ARGS>(args)...); } Base<T, ARGS...> *getCopy() override { return new functor(*this ); } private : CLASS_T obj; }; template <typename T, typename ...ARGS> class function ;template <typename T, typename ...ARGS>class function < T(ARGS...)> {public : function(T (*ptr)(ARGS...)) : ptr(new normal_function<T, ARGS...>(ptr)) {} template <typename CLASS_T> function(CLASS_T obj) : ptr(new functor<CLASS_T, T, ARGS...>(obj)){} T operator () (ARGS... args) { return ptr->run(forward<ARGS>(args)...); } function &operator =(const function<T(ARGS...)> &func) { delete this ->ptr; this ->ptr = func.ptr->getCopy(); return *this ; } ~function() { delete this ->ptr; } private : Base<T, ARGS...> *ptr; }; int func (int a, int b) { cout << "normal function : " ; return a + b; }; class ADD_MULT {public : ADD_MULT(int x) : x(x) {} int operator () (int a, int b) { cout << "functor : " ; return (a + b) * 2 ; } private : int x; }; int main () { ADD_MULT add_mult (2 ) ; function<int (int , int )> f1 = func; function<int (int , int )> f2 = add_mult; cout << f1(3 , 4 ) << endl ; cout << f2(3 , 4 ) << endl ; f1 = f2; cout << f1(3 , 4 ); return 0 ; } ENDS(function_impl) int main () { function_impl::main(); return 0 ; }
源码文件*.cpp 点我跳转:https://github.com/qzwl123/C-/tree/main/%E6%A8%A1%E6%9D%BF