一、为什么要有模板?
将类型参数化,可以实现算法与类型的分离,编写针对类型更加抽象的函数或者类。
二、函数模板
通用定义:
template<typename 类型形参1, ...>
返回类型 函数模板名 (形参表) { ... }
特化定义:
template<>

返回类型 函数模板名<类型实参1, ...> (形参表) { ... }

 1 /* 函数模板(模板函数)练习
 2  * */
 3 #include <iostream>
 4 #include <typeinfo>
 5 #include <cstring>
 6 using namespace std;
 7
 8
 9 template<typename T/*类型形式参数表*/>
10 //typename关键字声明了类型形式参数表,早期这里采用的关键字是class,早期就直接用关键字class来声明类型形式参数, 在这里class就是typename, typename就是class, 没有区别!
11 T Max (T x, T y)
12 {//编译期编译此处时,不进行实际编译,只进行基本的类型检查,当后期有模板的实例要进行编译时,根据实例化时候给出的实际类型参数进行编译,这称为"后期编译"。
13 //后期编译,在获得实际类型参数时进行编译,也就是说一个模板函数或许在编译期被编译为多个具体的函数。
14     cout << typeid (T).name () << endl;
15     return x > y ? x : y;
16 }
17
18 // 模板特化
19 template<>//缺少后部分编译器会报错,部分容错性比较好的编译器能够自动识别同名于模板函数的函数为其特化。
20 char* Max<char* /*可以省略,编译器可以根据后边括号中的char*隐式推断出来这里的char**/> (char* x, char* y)
21 {//当编译期获得实际类型参数是char*时,按照该特化的模板编译。
22     return strcmp (x, y) > 0 ? x : y;
23 }
24 template<typename T>
25 void foo (void) {
26     T t;
27     cout << typeid (t).name () << endl;
28 }
29 int main (void) {
30     cout << "输入两个整数:" << flush;
31     int nx, ny;
32     cin >> nx >> ny;
33     cout << "最大值:" << Max<int/*类型实际参数*/> (nx, ny) << endl;//获得Max的实际类型参数表后进行编译,这叫做"后期编译"。
34     cout << "输入两个字符串:" << flush;
35     string sx, sy;
36     cin >> sx >> sy;
37     cout << "最大值:" << Max (sx, sy) << endl;//编译器自动推断类型实际参数,最终编译函数string Max(string, string);
38     cout << "输入两个字符串:" << flush;
39     foo<int> ();//编译器不能自动推断类型实际参数,必须显式的给出类型实际参数表。
40     foo<double> ();
41     foo<string> ();
42
43     char cx[256], cy[256];
44     cin >> cx >> cy;
45     cout << "最大值:" << Max<char*> (cx, cy) << endl;//编译函数char* Max(chat*, char*);
46
47
48     return 0;
49 }

三、类模板
通用定义:
template<typename 类型形参1, ...>
class 类模板名 { ... };
全类特化:
template<>
class 类模板名<类型实参1, ...> { ... };
成员特化:
template<>

返回类型 类模板名<类型实参1, ...>::成员函数名 (形参表) { ... }

 1 /*类模板练习
 2  * */
 3 #include <iostream>
 4 #include <cstring>
 5 using namespace std;
 6 // 通用模板
 7 template<typename T>
 8 class Comparator {
 9 public:
10     Comparator (T x, T y) : m_x (x), m_y (y) {}
11     T min (void) const {
12         return m_x < m_y ? m_x : m_y;
13     }
14     T max (void) const {
15         return m_x > m_y ? m_x : m_y;
16     }
17 private:
18     T m_x;
19     T m_y;
20 };
21 /*
22 // 针对char*的全模板特化
23 template<>
24 class Comparator<char*> {
25 public:
26     Comparator (char* x, char* y) :
27         m_x (x), m_y (y) {}
28     char* min (void) const {
29         return strcmp (m_x, m_y) < 0 ? m_x : m_y;
30     }
31     char* max (void) const {
32         return strcmp (m_x, m_y) > 0 ? m_x : m_y;
33     }
34 private:
35     char* m_x;
36     char* m_y;
37 };
38 */
39 // 针对char*的成员函数特化
40 template<>
41 char* Comparator<char*>::min (void) const {
42     return strcmp (m_x, m_y) < 0 ? m_x : m_y;
43 }
44 template<>
45 char* Comparator<char*>::max (void) const {
46     return strcmp (m_x, m_y) > 0 ? m_x : m_y;
47 }
48 int main (void) {
49     cout << "输入两个整数:" << flush;
50     int nx, ny;
51     cin >> nx >> ny;
52     Comparator<int> cn (nx, ny);// 编译期使用实际类型参数表进行模板实例化,运行期使用实例化后的类进行对象实例化。
53     cout << "最小值:" << cn.min () << endl;
54     cout << "最大值:" << cn.max () << endl;
55     cout << "输入两个字符串:" << flush;
56     string sx, sy;
57     cin >> sx >> sy;
58     Comparator<string> cs (sx, sy);
59     cout << "最小值:" << cs.min () << endl;
60     cout << "最大值:" << cs.max () << endl;
61     cout << "输入两个字符串:" << flush;
62     char cx[256], cy[256];
63     cin >> cx >> cy;
64     Comparator<char*> cc (cx, cy);
65     cout << "最小值:" << cc.min () << endl;
66     cout << "最大值:" << cc.max () << endl;
67     return 0;
68 }

四、局部特化

 1 /*
 2  * 模板的局部特化
 3  * */
 4 #include <iostream>
 5 using namespace std;
 6 template<typename T1, typename T2>
 7 class A {
 8 public:
 9     A (void) {
10         cout << "A<T1,T2>" << endl;
11     }
12 };
13 template<typename T1>
14 class A<T1, int> {
15 public:
16     A (void) {
17         cout << "A<T1,int>" << endl;
18     }
19 };
20 template<>
21 class A<int, int> {
22 public:
23     A (void) {
24         cout << "A<int,int>" << endl;
25     }
26 };
27 template<typename T>
28 class B {
29 public:
30     B (void) {
31         cout << "B<T>" << endl;
32     }
33 };
34 template<typename T>
35 class B<T*> {
36 public:
37     B (void) {
38         cout << "B<T*>" << endl;
39     }
40 };
41 template<typename T>
42 class B<T[]> {
43 public:
44     B (void) {
45         cout << "B<T[]>" << endl;
46     }
47 };
48 template<typename T1, typename T2, typename T3>
49 class C {
50 public:
51     C (void) {
52         cout << "C<T1,T2,T3>" << endl;
53     }
54 };
55 template<typename T1, typename T2>
56 class C<T1, T2, T2> {
57 public:
58     C (void) {
59         cout << "C<T1,T2,T2>" << endl;
60     }
61 };
62 template<typename T1>
63 class C<T1, T1*, T1*> {
64 public:
65     C (void) {
66         cout << "C<T1,T1*,T1*>" << endl;
67     }
68 };
69 int main (void) {
70     // 特化程度高(具体化程度高,模板实例化程度高)的优先
71     A<double, double> a1;
72     A<double, int> a2;
73     A<int, int> a3;
74     // 针对指针和数组的特化优先
75     B<char> b1;
76     B<char*> b2;
77     B<char[]> b3;
78     // 匹配度高的特化优先
79     C<char, short, long> c1;
80     C<char, short, short> c2;
81     C<char, char*, char*> c3;
82     return 0;
83 }

五、非类型参数和缺省参数
1.非类型参数的实参仅限于常量或者常量表达式。

2.无论类型参数还是非类型参数都可以带有缺省值,而且和函数的缺省参数一样,模板的缺省参数也必须靠右。

 1 #include <iostream>
 2 using namespace std;
 3 template<typename T = int, size_t S = 5>
 4 class Array {
 5 public:
 6     T& operator[] (size_t i) {
 7         return m_array[i];
 8     }
 9     const T& operator[] (size_t i) const {
10         return const_cast<Array&> (*this) [i];
11     }
12     size_t size (void) const {
13         return S;
14     }
15     friend ostream& operator<< (ostream& os,
16         const Array& arr) {
17         for (size_t i = 0; i < arr.size (); ++i)
18             os << '(' << arr.m_array[i] << ')';
19         return os;
20     }
21 private:
22     T m_array[S];
23 };
24 int main (void) {
25     const /*volatile*/ int x = 3, y = 7;//对于具有常属性的变量,编译器在编译期进行优化,会把常属性的变量替换为常量,以图通过立即数来提高访问效率。通过关键字volatile可以取消编译器的这种优化。
26     Array<int, x+y> arr;//非类型实际参数只能是常量表达式
27     for (size_t i = 0; i < arr.size (); ++i)
28         arr[i] = i;
29     cout << arr << endl;
30     Array<Array<int, 4>, 3> m;
31     for (size_t i = 0; i < m.size (); ++i)
32         for (size_t j = 0; j < m[i].size (); ++j)
33             m[i][j] = i * m[i].size () + j;
34     cout << m << endl;
35     Array<double> a2;
36     Array<> a3;
37     return 0;
38 }

 1 #include <iostream>
 2 using namespace std;
 3
 4 template<typename T>
 5 class A {
 6 public:
 7     class B {};
 8 };
 9
10 template<typename T>
11 void foo (void) {
12     typename A<T>::B b;//直接写A<T>::B b;编译报错。因编译期初期不会将模板编译成代码,所以A<T>此时还是一个不明的模板类名称,取一个不明模板类作用域里面的B,在编译器进行模板的语法检查时候被编译器报错。可以通过关键字typename来告诉编译器A<T>是后期编译的一个类型名称。
13     //这里的typename不可以换为class.这里的typename关键字是告诉编译器A<T>::B是个类型名称
14 }
15
16
17 int main (void) {
18     foo<int> ();
19     return 0;
20 }

六、有关模板的其它问题

1.从模板继承

 1 /*
 2  * 类模板中的继承-从类模板继承
 3  * */
 4 #include <iostream>
 5 using namespace std;
 6 template<typename T>
 7 class A {
 8 public:
 9     A (const T& t) : m_t (t) {}
10     T m_t;
11 };
12 template<typename T, typename Y>
13 class B : public A<T>/*A是模板名称,A<T>是类名称*/ {
14 public:
15     B (const T& t, const Y& y) :
16         A<T> (t), m_y (y) {}
17     Y m_y;
18 };
19 int main (void) {
20     B<int, string> b (100, "hello");
21     cout << b.m_t << ' ' << b.m_y << endl;
22     return 0;
23 }

2.向模板派生

 1 /*
 2  * 向模板派生
 3  * 例如本例程:基类具体类,派生类是类模板
 4  *
 5  * */
 6 #include <iostream>
 7 using namespace std;
 8 template<typename BASE>
 9 class Shape : public BASE {
10 public:
11     void draw (void) const {
12         BASE::draw ();
13     }
14 };
15 class Rect {
16 public:
17     void draw (void) const {
18         cout << "绘制矩形..." << endl;
19     }
20 };
21 class Circle {
22 public:
23     void draw (void) const {
24         cout << "绘制圆形..." << endl;
25     }
26 };
27 int main (void) {
28     Shape<Rect> shape1;
29     shape1.draw ();
30     Shape<Circle> shape2;
31     shape2.draw ();
32     return 0;
33 }

3.模板中模板成员

1)模板型成员变量

2)模板型成员函数

3)模板型成员类型(内部类)

4.模板型模板实参

 1 /*
 2  *模板型成员变量
 3  */
 4 #include <iostream>
 5 using namespace std;
 6
 7 template<typename T>
 8 class A {
 9 public:
10     A (const T& t) : m_t (t) {}
11     T m_t;
12 };
13
14 template<typename T, typename Y>
15 class B {
16 public:
17     B (const T& t, const Y& y) :
18         m_a (t), m_y (y) {}
19     A<T> m_a;
20     Y m_y;
21 };
22
23
24 int main (void) {
25     B<int, string> b (100, "hello");
26     cout << b.m_a.m_t << ' ' << b.m_y << endl;
27     return 0;
28 }

 1 /*
 2  * 模板型成员函数
 3  * */
 4 #include <iostream>
 5 using namespace std;
 6 template<typename T>
 7 class A {
 8 public:
 9     A (const T& t) : m_t (t) {}
10     /*
11     template<typename Y>
12     void print (const Y& y) {
13         cout << m_t << ' ' << y << endl;
14     }
15     */
16     template<typename Y>
17     void print (const Y& y);
18     T m_t;
19 };
20 template<typename T>
21     template<typename Y>
22 void A<T>::print (const Y& y) {
23     cout << m_t << ' ' << y << endl;
24 }
25 int main (void) {
26     A<int> a (100);
27     a.print<string> ("hello");
28     return 0;
29 }

 1 /*
 2  * 模板型成员类型(内部类)
 3  *
 4  * */
 5 #include <iostream>
 6 using namespace std;
 7 template<typename T, typename Y>
 8 class A {
 9 public:
10     A (const T& t, const Y& y) :
11         m_t (t), m_b (y) {}
12     /*
13     template<typename X>
14     class B {
15     public:
16         B (const X& x) : m_x (x) {}
17         X m_x;
18     };
19     */
20     template<typename X> class B;//声明模板B
21     T m_t;
22     B<Y> m_b;
23 };
24 template<typename T, typename Y>
25     template<typename X>
26 class A<T, Y>::B {
27 public:
28     B (const X& x) : m_x (x) {}
29     X m_x;
30 };
31 int main (void) {
32     A<int, string> a (100, "hello");
33     cout << a.m_t << ' ' << a.m_b.m_x << endl;
34     return 0;
35 }

 1 /*
 2  * 模板型模板实参(模板作为模板的实参)
 3  *
 4  * */
 5 #include <iostream>
 6 using namespace std;
 7 template<typename T>
 8 class A {
 9 public:
10     A (const T& t) : m_t (t) {}
11     T m_t;
12 };
13
14 template<typename X, typename Z,
15     template<typename T>  class Y/*Y是一个模板*/>//也可以写作template<class X, class Z, template<class T> class Y>
16 class B {
17 public:
18     B (const X& i, const Z& s) :
19         m_i (i), m_s (s) {}
20     Y<X> m_i;
21     Y<Z> m_s;
22 };
23 int main (void) {
24     B<int, string, A> b (100, "hello");
25     cout << b.m_i.m_t << ' ' << b.m_s.m_t << endl;
26     return 0;
27 }

七、容器和迭代器

  1 /*
  2  * 基于双向链表的容器的实现
  3  *
  4  * */
  5 #include <iostream>
  6 #include <stdexcept>
  7 #include <cstring>
  8 using namespace std;
  9 // 双向线性链表容器模板
 10 template<typename T>
 11 class List {
 12 public:
 13     // 构造、析构、拷贝构造、拷贝赋值
 14     List (void) : m_head (NULL), m_tail (NULL) {}
 15     ~List (void) {
 16         clear ();
 17     }
 18     List (const List& that) : m_head (NULL),
 19         m_tail (NULL) {
 20         for (Node* node = that.m_head; node;
 21             node = node->m_next)
 22             push_back (node->m_data);
 23     }
 24     List& operator= (const List& that) {
 25         if (&that != this) {
 26             List list (that);
 27             swap (m_head, list.m_head);
 28             swap (m_tail, list.m_tail);
 29         }
 30         return *this;
 31     }
 32     // 获取首元素
 33     T& front (void) {
 34         if (empty ())
 35             throw underflow_error ("链表下溢!");
 36         return m_head->m_data;
 37     }
 38     const T& front (void) const {
 39         return const_cast<List*> (this)->front ();
 40     }
 41     // 向首部压入
 42     void push_front (const T& data) {
 43         m_head = new Node (data, NULL, m_head);
 44         if (m_head->m_next)
 45             m_head->m_next->m_prev = m_head;
 46         else
 47             m_tail = m_head;
 48     }
 49     // 从首部弹出
 50     void pop_front (void) {
 51         if (empty ())
 52             throw underflow_error ("链表下溢!");
 53         Node* next = m_head->m_next;
 54         delete m_head;
 55         m_head = next;
 56         if (m_head)
 57             m_head->m_prev = NULL;
 58         else
 59             m_tail = NULL;
 60     }
 61     // 获取尾元素
 62     T& back (void) {
 63         if (empty ())
 64             throw underflow_error ("链表下溢!");
 65         return m_tail->m_data;
 66     }
 67     const T& back (void) const {
 68         return const_cast<List*> (this)->back ();
 69     }
 70     // 向尾部压入
 71     void push_back (const T& data) {
 72         m_tail = new Node (data, m_tail);
 73         if (m_tail->m_prev)
 74             m_tail->m_prev->m_next = m_tail;
 75         else
 76             m_head = m_tail;
 77     }
 78     // 从尾部弹出
 79     void pop_back (void) {
 80         if (empty ())
 81             throw underflow_error ("链表下溢!");
 82         Node* prev = m_tail->m_prev;
 83         delete m_tail;
 84         m_tail = prev;
 85         if (m_tail)
 86             m_tail->m_next = NULL;
 87         else
 88             m_head = NULL;
 89     }
 90     // 删除所有匹配元素
 91     void remove (const T& data) {
 92         for (Node* node = m_head, *next; node;
 93             node = next) {
 94             next = node->m_next;
 95             if (equal (node->m_data, data)) {
 96                 if (node->m_prev)
 97                     node->m_prev->m_next =
 98                         node->m_next;
 99                 else
100                     m_head = node->m_next;
101                 if (node->m_next)
102                     node->m_next->m_prev =
103                         node->m_prev;
104                 else
105                     m_tail = node->m_prev;
106                 delete node;
107             }
108         }
109     }
110     // 清空
111     void clear (void) {
112         for (Node* next; m_head; m_head = next) {
113             next = m_head->m_next;
114             delete m_head;
115         }
116         m_tail = NULL;
117     }
118     // 判空
119     bool empty (void) const {
120         return ! m_head && ! m_tail;
121     }
122     // 获取大小
123     size_t size (void) const {
124         size_t count = 0;
125         for (Node* node = m_head; node;
126             node = node->m_next)
127             ++count;
128         return count;
129     }
130     // 插入输出流
131     friend ostream& operator<< (ostream& os,
132         const List& list) {
133         for (Node* node = list.m_head; node;
134             node = node->m_next)
135             os << *node;
136         return os;
137     }
138 private:
139     // 节点
140     class Node {
141     public:
142         Node (const T& data = 0, Node* prev = NULL,
143             Node* next = NULL) : m_data (data),
144             m_prev (prev), m_next (next) {}
145         friend ostream& operator<< (ostream& os,
146             const Node& node) {
147             return os << '(' << node.m_data << ')';
148         }
149         T m_data; // 数据
150         Node* m_prev; // 前指针
151         Node* m_next; // 后指针
152     };
153     bool equal (const T& a, const T& b) const {
154         return a == b;
155     }
156     Node* m_head; // 头指针
157     Node* m_tail; // 尾指针
158 public:
159     // 正向迭代器
160     class Iterator {
161     public:
162         Iterator (Node* head = NULL,
163             Node* tail = NULL, Node* node = NULL) :
164             m_head (head), m_tail (tail),
165             m_node (node) {}
166         bool operator== (const Iterator& it) const {
167             return m_node == it.m_node;
168         }
169         bool operator!= (const Iterator& it) const {
170             return ! (*this == it);
171         }
172         Iterator& operator++ (void) {
173             if (m_node)
174                 m_node = m_node->m_next;
175             else
176                 m_node = m_head;
177             return *this;
178         }
179         const Iterator operator++ (int) {
180             Iterator old = *this;
181             ++*this;
182             return old;
183         }
184         Iterator& operator-- (void) {
185             if (m_node)
186                 m_node = m_node->m_prev;
187             else
188                 m_node = m_tail;
189             return *this;
190         }
191         const Iterator operator-- (int) {
192             Iterator old = *this;
193             --*this;
194             return old;
195         }
196         T& operator* (void) const {
197             return m_node->m_data;
198         }
199         T* operator-> (void) const {
200             return &**this;
201         }
202     private:
203         Node* m_head;
204         Node* m_tail;
205         Node* m_node;
206         friend class List;
207     };
208     Iterator begin (void) {
209         return Iterator (m_head, m_tail, m_head);
210     }
211     Iterator end (void) {
212         return Iterator (m_head, m_tail);
213     }
214     Iterator insert (Iterator loc, const T& data) {
215         if (loc == end ()) {
216             push_back (data);
217                return Iterator (m_head, m_tail,m_tail);
218         }
219         else {
220             Node* node = new Node (data,
221                 loc.m_node->m_prev, loc.m_node);
222             if (node->m_prev)
223                 node->m_prev->m_next = node;
224             else
225                 m_head = node;
226             node->m_next->m_prev = node;
227             return Iterator (m_head, m_tail, node);
228         }
229     }
230     Iterator erase (Iterator loc) {
231         if (loc == end ())
232             throw invalid_argument ("无效迭代器!");
233         if (loc.m_node->m_prev)
234             loc.m_node->m_prev->m_next =
235                 loc.m_node->m_next;
236         else
237             m_head = loc.m_node->m_next;
238         if (loc.m_node->m_next)
239             loc.m_node->m_next->m_prev =
240                 loc.m_node->m_prev;
241         else
242             m_tail = loc.m_node->m_prev;
243         Node* next = loc.m_node->m_next;
244         delete loc.m_node;
245         return Iterator (m_head, m_tail, next);
246     }
247 };
248 // 针对const char*的特化
249 template<>
250 bool List<const char*>::equal (const char* const& a,
251     const char* const& b) const {
252     return strcmp (a, b) == 0;
253 }
254 // 测试用例
255 int main (void) {
256     try {
257         List<int> list1;
258         list1.push_front (20);
259         list1.push_front (10);
260         list1.push_back (30);
261         list1.push_back (40);
262         cout << list1 << endl;
263         cout << list1.front () << ' ' <<
264             list1.back () << endl;
265         list1.pop_front ();
266         list1.pop_back ();
267         cout << list1 << endl;
268         ++list1.front ();
269         --list1.back ();
270         cout << list1 << endl;
271         list1.push_back (21);
272         list1.push_back (25);
273         list1.push_back (21);
274         list1.push_back (21);
275         cout << list1 << endl;
276         list1.remove (21);
277         cout << list1 << endl;
278         List<int> list2 = list1;
279         cout << list2 << endl;
280         list2.back () = 100;
281         cout << list2 << endl;
282         cout << list1 << endl;
283         list2 = list1;
284         cout << list2 << endl;
285         list2.front () = 100;
286         cout << list2 << endl;
287         cout << list1 << endl;
288         cout << list1.size () << endl;
289         list1.clear ();
290         cout << list1 << endl;
291         cout << boolalpha << list1.empty () << endl;
292 //        List<string> list3;
293         List<const char*> list3;
294         list3.push_back ("beijing");
295         list3.push_back ("tianjin");
296         list3.push_front ("tianjin");
297         list3.push_back ("shanghai");
298         list3.push_back ("beijing");
299         cout << list3 << endl;
300         list3.remove (string ("beijing").c_str ());
301         cout << list3 << endl;
302         for (List<const char*>::Iterator it =
303             list3.begin (); it != list3.end ();
304             ++it)
305             cout << *it << ' ';
306         cout << endl;
307         List<const char*>::Iterator it =
308             list3.begin ();
309         it++;
310         it = list3.insert (it, "chongqing");
311         cout << list3 << endl;
312         list3.erase (it);
313         cout << list3 << endl;
314     }
315     catch (exception& ex) {
316         cout << ex.what () << endl;
317         return -1;
318     }
319     return 0;
320 }

转载于:https://www.cnblogs.com/libig/p/4746724.html

Standard C++ Episode 10相关推荐

  1. Standard C Episode 1

    Standard C Episode 1 计算机内存可以记录大量的信息,只有记录在内存中的信息才是可以使用的.计算机的内存管理者是操作系统.程序可以根据需要向操作系统申请存储区,所有存储区必须先申请并 ...

  2. Normal map (Bump mapping) 法线贴图(凹凸映射) Standard Shader系列10

    Normal map (Bump mapping) 法线贴图(凹凸映射) 本文档主要是对Unity官方手册的个人理解与总结(其实以翻译记录为主:>) 仅作为个人学习使用,不得作为商业用途,欢迎转 ...

  3. Standard C++ Episode 7

    六.C++的I/O流库 C:fopen/fclose/fread/fwrite/fprintf/fscanf/fseek/ftell... C++:对基本的I/O操作做了类的封装,其功能没有任何差别, ...

  4. Standard C Episode 8

    C语言函数和程序结构 通过函数可以把大的计算任务分解成若干个较小任务,从而使得思路更加清晰,同时函数也大大提高了代码的复用率,提高了工作效率.要注意的是多函数之间应该尽可能地高聚合低耦合.另一方面,一 ...

  5. javaScript计算体重:开发一款软件,根据公式(身高-108)*2=体重,可以有10斤左右的浮动。来观察测试者体重是否合适(代码)

    题目:开发一款软件,根据公式(身高-108)*2=体重,可以有10斤左右的浮动.来观察测试者体重是否合适 代码: var height = prompt("请输入身高:"); va ...

  6. 40奇点,天网,计算机的未来

    计算机速成课第40集 奇点,天网,计算机的未来 超喜欢此系列, 整理成文字笔记方便重复阅读. 01:21 普适计算 Ubiquitous Computing 04:55 奇点 Singularity ...

  7. greenplum安装札记(待完善)

    1.安装配置 1.1硬件配置 硬件服务器用到某私有云中ip段为192.168.228.111-192.168.228.120的十台服务器,相关主要配置如下表: 类别 主机名 IP 内存 硬盘 主要目录 ...

  8. 我怎样才能找到带有Mathematica的Waldo?

    本文翻译自:How do I find Waldo with Mathematica? This was bugging me over the weekend: What is a good way ...

  9. python开发框架 代码生成_我的第一个python web开发框架(28)——定制ORM(四)...

    在数据库操作时,新增记录也是必不可少的,接下来我们应用字典的特性来组合sql语句 先上产品新增接口代码 1 @post('/api/product/')2 defcallback():3 " ...

最新文章

  1. Ctex软件介绍安装破解(是WinEdt_v6.0破解)
  2. oracleDBA-D1
  3. Java线程池ThreadPoolExecutor
  4. 提升用户体验,你不得不知道的事儿——三种提醒框的微技巧
  5. Oracle高级SQL培训与讲解
  6. live555的安装 RTSP点播消息流程实例(客户端:VLC, RTSP服务器:LIVE555 Media Server)
  7. VC6.0 中的__asm语句
  8. java定义一个类显示没有_Java 中的每个类都至少有一个构造方法,一个类中如果没有定义构造方法,系统会自动为这个类创建一个默认的构造方法。_学小易找答案...
  9. maven项目包导不进去_IntelliJ Idea下Maven插件使用技巧
  10. 错误:cc1: error: unrecognized command line option “-m32”
  11. cenos7部署samba
  12. m.555lu.co list.php,CST 仿真色散曲线
  13. 计算机系统端口445,如何关闭445端口,教您如何关闭系统端口
  14. 多智能体强化学习之值函数分解:VDN、QMIX、QTRAN系列优缺点分析(转载)
  15. ShuffleNet: An Extremely Efficient Convolutional Neural Network for Mobile Devices (翻译)
  16. Win10系统高分辨率缩放时应用程序字体模糊
  17. FAT文件系统引导扇区学习总结
  18. html embed用法
  19. 云原生爱好者周刊:mist.io 开源多云管理平台
  20. 优酷路由器刷openwrt固件一

热门文章

  1. cloudstack centOS安装(二)
  2. Python学习笔记-包
  3. ssh 双机互信配置记要
  4. linux 进程和线程
  5. Ubuntu 系统安装APACHE PHP MYSQL
  6. 软件项目质量管理经验谈
  7. php软件开发--html进阶
  8. 开源 sql 代码提示工具_有关如何计划开源活动的提示
  9. 国防现代化的数据_Linux容器如何解决国防虚拟化问题
  10. openstack 学习_需要IT工作吗? 学习OpenStack