Thực ra không có nhiều hiểu biết sâu sắc, vì chưa cảm nhận được tác dụng của các ví dụ này, ghi lại trước đã
1 #include <iostream>
2
3 using namespace std;
4 class memory_allocator {
5
6 };
7
8 template<class Type, class Allocator = memory_allocator>
9 class dynamic_array {
10 public:
11 void exchange(dynamic_array<Type, Allocator>&) {
12 cout << "exchange()" << endl;
13 }
14 };
15
16 template<class Type,class Allocator>
17 inline void exchange(dynamic_array<Type, Allocator>& x,dynamic_array<Type, Allocator>& y){
18 x.exchange(y);
19 }
20
21
22 int main(int argc, char **argv) {
23 dynamic_array<int> x,y;
24 exchange(x,y);
25 return 0;
26 }
Dưới đây dùng để kiểm tra xem class template có thể chứa template khác không
1 #include <iostream>
2
3 using namespace std;
4 class memory_allocator {
5
6 };
7
8 template<class Type, class Allocator = memory_allocator>
9 class dynamic_array {
10 public:
11 typedef Type value_type;
12 typedef value_type* pointer;
13 //Kiểm tra xem class template có thể chứa template khác không
14 template<class Input>
15 void add_elements(pointer position, Input start, Input end) {
16 cout << "add_elements()" << endl;
17 }
18 };
19
20 int main(int argc, char **argv) {
21 int data[5] = { 0, 1, 2, 3, 4 };
22
23 dynamic_array<int> x;
24 dynamic_array<int>::pointer ite;
25 x.add_elements(ite, data, data + 5);
26 return 0;
27 }
Kiểm tra xem tham số template có thể được đặt giá trị mặc định dựa trên tham số template trước đó không
1 #include <iostream>
2 #include <cstddef>
3
4 using namespace std;
5
6 class memory_allocator {
7
8 };
9
10 template<class Type, class Allocator = memory_allocator, size_t BufferSize = 0>
11 class double_ended_queue {
12 public:
13 double_ended_queue() {
14 cout << "double_ended_queue" << endl;
15 }
16 };
17
18 template<class Type, class Container = double_ended_queue<Type>>
19 class stack_container {
20 public:
21 stack_container() {
22 cout << "stack_container" << endl;
23 }
24 private:
25 Container storage;
26 };
27
28 int main(int argc, char **argv) {
29 stack_container<int> x;
30 return 0;
31 }
Kết quả chạy:
double_ended_queue
stack_container
Thành viên biến được khởi tạo trước, sau đó mới đến hàm tạo.
//Ghi chú nói rằng kiểm tra xem class template có thể có tham số template không phải kiểu
//Nhưng tôi không tìm thấy tham số nào không phải kiểu
1 #include <iostream>
2 #include <cstddef>
3
4 using namespace std;
5
6 class memory_allocator {
7
8 };
9
10 inline size_t calculate_buffer_size(size_t count, size_t size) {
11 return count != 0 ? count : (size < 512 ? size_t(512 / size) : size_t(1));
12 }
13
14 template<class Type, class Reference, class Pointer, size_t BufferSize>
15 struct deque_iterator {
16 typedef deque_iterator <Type, Type&, Type*, BufferSize> iterator;
17 typedef deque_iterator <Type, const Type&, const Type*, BufferSize> const_iterator;
18 static size_t get_buffer_size() {
19 return calculate_buffer_size(BufferSize, sizeof(Type));
20 }
21 };
22
23 template<class Type, class Allocator = memory_allocator, size_t BufferSize = 0>
24 class double_ended_queue {
25 public:
26 typedef deque_iterator <Type, Type&, Type*, BufferSize> iterator;
27 };
28
29 int main(int argc, char **argv) {
30 cout << double_ended_queue<int>::iterator::get_buffer_size() << endl;
31 cout << double_ended_queue<int, memory_allocator, 64>::iterator::get_buffer_size() << endl;
32 return 0;
33 }
Kết quả chạy
128
64
Sau khi xem qua mã nguồn STL hoàn chỉnh, tôi chỉ cảm thấy cách viết này rất xuất sắc, nhưng không biết tại sao lại viết như vậy.
Tìm hiểu thì biết non-type là BufferSize. Nhưng thực sự vẫn chưa hiểu rõ điểm ưu việt của iterator được định nghĩa như vậy
//bound friend templates chờ khi nào tìm được nơi sử dụng
1 #include <iostream>
2 #include <cstddef>
3
4 using namespace std;
5
6 class memory_allocator {
7
8 };
9
10 template<class Type, class Allocator = memory_allocator, size_t BufferSize = 0>
11 class double_ended_queue {
12 public:
13 double_ended_queue() {
14 cout << "double_ended_queue" << ' ';
15 }
16 };
17
18 template<class Type, class Container>
19 class stack_container;
20
21 template<class Type, class Container>
22 bool operator_equals(const stack_container<Type, Container>& x, const stack_container<Type, Container>& y);
23
24 template<class Type, class Container>
25 bool operator_less(const stack_container<Type, Container>& x, const stack_container<Type, Container>& y);
26
27 template<class Type, class Container = double_ended_queue<Type>>
28 class stack_container {
29 //Cách này được chấp nhận
30 /*
31 friend bool operator_equals<Type>(const stack_container<Type, Container>& x,
32 const stack_container<Type, Container>& y);
33 friend bool operator_less <Type>(const stack_container<Type, Container>& x,
34 const stack_container<Type, Container>& y);
35 */
36 //Cách này không được chấp nhận
37 /*
38 friend bool operator_equals(const stack_container<Type, Container>& x,
39 const stack_container<Type, Container>& y);
40 friend bool operator_less(const stack_container<Type, Container>& x,
41 const stack_container<Type, Container>& y);
42 */
43 //Không thể bỏ <> sau toán tử
44 //Có thể bỏ <> trong tham số
45 friend bool operator_equals<Type, Container>(const stack_container& x,
46 const stack_container<Type, Container>& y);
47 friend bool operator_less <>(const stack_container<Type>& x, const stack_container<Type, Container>& y);
48 public:
49 stack_container() {
50 cout << "stack_container" << endl;
51 }
52 private:
53 Container storage;
54 };
55
56 template<class Type, class Container>
57 bool operator_equals(const stack_container<Type, Container>& x, const stack_container<Type, Container>& y) {
58 cout << "operator_equals" << '\t';
59 return 1;
60 }
61
62 template<class Type, class Container>
63 bool operator_less(const stack_container<Type, Container>& x, const stack_container<Type, Container>& y) {
64 cout << "operator_less" << '\t';
65 return 1;
66 }
67
68 int main(int argc, char **argv) {
69 stack_container<int> x;
70 stack_container<int> y;
71
72 cout << (x == y) << endl;
73 cout << (x < y) << endl;
74 return 0;
75 }
Specialization rõ ràng (explicit specialization)
Còn có specialization riêng, có thể tìm hiểu thêm
Chi tiết về specialization và partial specialization trong C++ template
Hóa ra specialization riêng chính là những gì được viết trong C++ template一些体悟(2), chỉ đổi tên, ở đó gọi là thiết kế đặc biệt
Còn liên quan đến vấn đề A a(); là khai báo một hàm thay vì một đối tượng, cần cẩn thận
1 #include <iostream>
2 #include <cstddef>
3
4 using namespace std;
5
6 #define TEMPLATE_NULL template<>
7
8 template<class Key>
9 class HashFunction {
10 public:
11 HashFunction() {
12 cout << "Construct HashFunction<T>" << endl;
13 }
14
15 void operator()() {
16 cout << "HashFunction<T>" << endl;
17 }
18 };
19
20 //explicit specialization
21 TEMPLATE_NULL
22 class HashFunction<char> {
23 public:
24 HashFunction() {
25 cout << "Construct HashFunction<char>" << endl;
26 }
27 void operator()() {
28 cout << "HashFunction<char" << endl;
29 }
30 };
31
32 int main(int argc, char **argv) {
33 // HashFunction<long> obj1(); //Khai báo một hàm thay vì một đối tượng
34 HashFunction<long> obj1;
35 HashFunction<char> obj2;
36 obj1();
37 obj2();
38 return 0;
39 }
Kết quả chạy
Construct HashFunction<T>
Construct HashFunction<char>
HashFunction<T>
HashFunction<char