Table of contents
2.1 linked list implementation
3. Matching rules for template specialization
(1) Matching rules for class templates
(2) Matching rules for function templates
1. Template
1.1 Type Template
#include <stdio.h> #include <iostream> using namespace std; #if 1 int add(int a, int b) { return a+b; } double add(double a, double b) { return a+b; } #else template<typename XXX> XXX add(XXX a, XXX b) { return a+b; } #endif int main() { cout << add(1,2) << endl; cout << add(1.1,2.2) << endl; }
arr.c >> arr.h : Append the previous file to the tail of the following file
#ifndef _ARR_ #define _ARR_ #include <iostream> using namespace std; template <typename XXX> class ARR{ public: ARR():tail(0){ } void addtail(XXX data); void show(void); private: XXX data[100]; int tail; }; template <typename XXX> void ARR<XXX>::addtail(XXX data) { this->data[tail++] = data; } template <typename XXX> void ARR<XXX>::show(void) { int i = 0; for(;i<tail; i++) cout<< data[i] <<','; cout<<endl; } #endif
template <typename XXX> must be written once every time it is used
#include "arr.h" int main() { ARR<int> arr; arr.addtail(1); arr.addtail(2); arr.addtail(3); arr.addtail(4); arr.show(); ARR<double> arr1; arr1.addtail(1.1); arr1.addtail(22.3); arr1.addtail(3.5); arr1.addtail(4.9); arr1.show(); }
1.2 Non-Type Templates
#define _ARR_ #include <iostream> using namespace std; template <typename XXX, int SIZE> class ARR{ public: ARR():tail(0){ } void addtail(XXX data); void show(void); private: XXX data[SIZE]; int tail; }; template <typename XXX, int SIZE> void ARR<XXX, SIZE>::addtail(XXX data) { this->data[tail++] = data; } template <typename XXX, int SIZE> void ARR<XXX, SIZE>::show(void) { int i = 0; for(;i<tail; i++) cout<< data[i] <<','; cout<<endl; } #endif
#include "arr.h" int main() { ARR<int, 100> arr; arr.addtail(1); arr.addtail(2); arr.addtail(3); arr.addtail(4); arr.show(); ARR<double, 1000> arr1; arr1.addtail(1.1); arr1.addtail(22.3); arr1.addtail(3.5); arr1.addtail(4.9); arr1.show(); }
#include <stdio.h> #include <iostream> using namespace std; #if 0 int add(int a, int b) { return a+b; } double add(double a, double b) { return a+b; } #else template<typename XXX> XXX add(XXX a, XXX b) { return a+b; } #endif template<> bool add(bool a, bool b) { if (a == true && b == true) return true; return false; } int main() { cout << add(1,2) << endl; cout << add(1.1,2.2) << endl; cout << add(true, false) <<endl; cout << add(true, true) <<endl; }
2. STL
2.1 linked list implementation
#include <iostream> #include <ostream> using namespace std; class myList{ struct Node{ Node(int x, Node *ptr=NULL):data(x), next(ptr) { } int data; Node *next; }; public: myList():head(NULL) { } ~myList() { while(head) { Node *tem = head; head = head->next; delete tem; } } void insert_head(int data) { Node *node = new Node(data); node->next = head; head = node; } friend ostream &operator<<(ostream &out, const myList &list); private: Node *head; }; ostream &operator<<(ostream &out, const myList &list) { myList::Node *tem = list.head; while(tem) { out<< tem->data <<','; tem = tem->next; } out << endl; return out; } int main() { myList list; list.insert_head(1); list.insert_head(2); list.insert_head(4); list.insert_head(3); cout << list; }
2.2 Iterators
C++ iterator (STL iterator) iterator detailed
Baidu Encyclopedia - Verification
#include <iostream> #include <ostream> using namespace std; class myList{ struct Node{ Node(int x, Node *ptr=NULL):data(x), next(ptr) { } int data; Node *next; }; public: class iterator{ public: iterator(Node *ptr=NULL):pos(ptr) { } iterator &operator++(int) { if(NULL != pos) pos = pos->next; return *this; } int &operator*() { return pos->data; } bool operator!=(iterator x) { return pos != x.pos; } private: Node *pos; }; public: myList():head(NULL) { } ~myList() { while(head) { Node *tem = head; head = head->next; delete tem; } } void insert_head(int data) { Node *node = new Node(data); node->next = head; head = node; } iterator begin() { return iterator(head); } iterator end() { return iterator(NULL); } friend ostream &operator<<(ostream &out, const myList &list); private: Node *head; }; ostream &operator<<(ostream &out, const myList &list) { myList::Node *tem = list.head; while(tem) { out<< tem->data <<','; tem = tem->next; } out << endl; return out; } int main() { myList list; list.insert_head(1); list.insert_head(2); list.insert_head(4); list.insert_head(3); cout << list; myList::iterator i = list.begin(); while(i != list.end() ) { cout << *i <<endl; i++; } }
2.3 STL container
Let's template the previous iterator linked list:
#include <iostream> #include <ostream> using namespace std; template <typename T> class myList{ struct Node{ Node(T x, Node *ptr=NULL):data(x), next(ptr) { } T data; Node *next; }; public: class iterator{ public: iterator(Node *ptr=NULL):pos(ptr) { } iterator &operator++(int) { if(NULL != pos) pos = pos->next; return *this; } int &operator*() { return pos->data; } bool operator!=(iterator x) { return pos != x.pos; } private: Node *pos; }; public: myList():head(NULL) { } ~myList() { while(head) { Node *tem = head; head = head->next; delete tem; } } void insert_head(T data) { Node *node = new Node(data); node->next = head; head = node; } iterator begin() { return iterator(head); } iterator end() { return iterator(NULL); } template <typename X> friend ostream &operator<<(ostream &out, const myList<X> &list); private: Node *head; }; template <typename X> ostream &operator<<(ostream &out, const myList<X> &list) { typename myList<X>::Node *tem = list.head; while(tem) { out<< tem->data <<','; tem = tem->next; } out << endl; return out; } int main() { myList<int> list; list.insert_head(1); list.insert_head(2); list.insert_head(4); list.insert_head(3); cout << list; myList<int>::iterator i = list.begin(); while(i != list.end() ) { cout << *i <<endl; i++; } }
For example, vector
#include <stdio.h> #include <iostream> #include <vector> using namespace std; int main() { #if 1 vector<int> arr; arr.push_back(1); arr.push_back(2); arr.push_back(3); arr.push_back(4); arr.push_back(5); arr.push_back(6); #endif vector<int>::iterator i = arr.begin(); while(i != arr.end() ) { cout << *i << endl; i++; } }
If it is a double type
#include <stdio.h> #include <iostream> #include <vector> using namespace std; int main() { #if 0 vector<int> arr; arr.push_back(1); arr.push_back(2); arr.push_back(3); arr.push_back(4); arr.push_back(5); arr.push_back(6); #else vector<double> arr; arr.push_back(1.2); arr.push_back(1.2); arr.push_back(1.2); arr.push_back(1.2); arr.push_back(1.2); arr.push_back(1.2); #endif // vector<int>::iterator i = arr.begin(); vector<double>::iterator i = arr.begin(); while(i != arr.end() ) { cout << *i << endl; i++; } }
Combine vector and list
#include <iostream> #include <vector> #include <list> using namespace std; int main() { #if 0 vector<int> arr; arr.push_back(1); arr.push_back(2); arr.push_back(3); arr.push_back(4); arr.push_back(5); #endif // vector<double> arr; list<double> arr; arr.push_back(1.2); arr.push_back(1.2); arr.push_back(1.2); arr.push_back(1.2); arr.push_back(1.2); // vector<int>::iterator i = arr.begin(); // vector<double>::iterator i = arr.begin(); list<double>::iterator i = arr.begin(); while(i != arr.end() ) { cout<< *i <<endl; i++; } }
map:
#include <iostream> #include <map> using namespace std; int main() { map<string, string> user_passwd; user_passwd.insert(user_passwd.begin(), pair<string, string>("aaa", "1111") ); user_passwd.insert(user_passwd.begin(), pair<string, string>("aaa4", "114411") ); user_passwd.insert(user_passwd.begin(), pair<string, string>("aaa2", "111331") ); user_passwd.insert(user_passwd.begin(), pair<string, string>("aaa3", "111441") ); map<string, string>::iterator i = user_passwd.begin(); while(i != user_passwd.end()) { cout<< (*i).first<< ',' <<(*i).second <<endl; i++; } cout<< user_passwd["aaa2"] << endl; }
2.4 STL algorithm
#include <iostream> #include<algorithm> using namespace std; bool cmp(int a, int b) { return a>b; } void show(int data) { cout<< data<< endl; } bool fcmp(int data) { return data == 34; } int main() { //vector<int> arr; int arr[] = {1,1234,23,4,23,42,34,23,42,34,2,2,2,444,22}; int n = sizeof(arr)/sizeof(int); int *p = find_if(arr, arr+n, fcmp); if(p != arr+n) cout<<"got it !\n"; cout <<"num of 34: "<< count_if(arr, arr+n, fcmp) << endl; /* for(int i = 0; i<n; i++) cout <<arr[i]<<','; cout<<endl; */ for_each(arr, arr+n, show); sort(arr, arr+n); // sort(arr, arr+n, cmp); cout<<"xxxxxxxxxxxxxxxxxxx\n"; unique(arr, arr+n); for_each(arr, arr+n, show); /* for(int i = 0; i<n; i++) cout <<arr[i]<<','; cout<<endl; */ }
3. Matching rules for template specialization
(1) Matching rules for class templates
Optimized over subspecialized, i.e. the one with the most exact match of template parameters has the highest priority
example:
template <class T> class vector{//…//}; // (a) common type
template <class T> class vector<T*>{//…//}; // (b) specialization for pointer types
template <> class vector <void*>{//…//}; // (c) specialize void*
Every type can be used as a parameter of ordinary type (a), but only pointer type can be used as a parameter of (b), and only void* can be used as a parameter of (c)
(2) Matching rules for function templates
Non-template functions have the highest precedence. If there is no matching non-template function, then the best matching and most specialized function has high priority
example:
template <class T> void f(T);the// (d)
template <class T> void f(int, T, double); // (e)
template <class T> void f(T*); // (f)
template <> void f<int> (int) ; // (g)
void f(double); // (h)
bool b;
int i;
double d;
f(b); // call (d) with T = bool
f(i,42,d) // call(e) with T = int
f(&i) ; // call(f) with T = int*
f(d); // call(g)
references
[1] Bjarne Stroustrup, The C++ Programming Language (Special Edition), Addison Wesley,2000
[2] Nicolai M.Josuttis, The C++ Standard Library – A Tutorial and Reference ,Addison Wesley,1999
[3] Stanley Lippman and Josée Lajoie ,C++ Primier, 3rd Edition ,Addison Wesley Longman ,1998
---------------------------------------------------------------------------------------------------------------------------------
Recently, I have been a little obsessed with reading books, and there are a few sentences that feel very reasonable to record:
If you want to maintain an independent personality, you must be financially independent. Even if you are only partly independent, you can live a peaceful life. After get off work, you can do part-time jobs, start a small business, and get a certificate. I think this is a very positive state. Don't be too little, the accumulation of less makes more, opportunities are reserved for those who are prepared~~
"People are very complicated things. No matter who you meet, it is a practice. Only by maintaining yourself can you enjoy life!"
Love is meeting the right person at the right time. The key is the right time. There is nothing to regret about this, because life is long, and there will be many suitable people. There is always someone waiting to be with you at the right time. meet~~"
A system, especially a highly professional system, is time-consuming and labor-intensive. Those who understand it regard it as a treasure, and those who do not understand it treat it as a pile of waste paper. Nonsense. This is the difference between people. Some people can always maintain their enthusiasm. No matter how twittering people around them are, they always know what they want. Even if you can't learn anything, it's good to have a long experience. Some people are always complaining, and rarely calm down to weigh the pros and cons. Most of the time, they are just following the crowd. When others complain, I also complain. Others may just talk about it. Only you take it seriously, all kinds of self-righteousness, All kinds of slamming others for being stupid, watching the people around him get promoted one by one, but in the end they didn't realize that the clown was actually just himself.
---------------------------------------------------------------------------------------------------------------------------------