16.1.5 non-type template parameters do not have to be all types. Template <class T, size_t n> void array_init (T (& ARR) [N]) {cout <"n =" <n <Endl; for (size_t I = 0; I! = N; I ++) Arr [I] = 0;} n is not a type template parameter. Call: int A [30]; array_init (a); then, if the parameter n is 30.16.1.6, it is legal to compile the program generated by the generic program using the template function, depends on the Operations used in the function and the operations supported by the types used. The programmer must ensure that the type of the function arguments supports these operations. However, it is best to set as few real parameter types as possible when writing template code. 16.2 The instantiation compiler uses a template to generate a specific version of the specified class or function, which is called Instantiation. Key Point: instantiation is completed during compilation. The class template is instantiated when the actual template type is referenced. The function template is instantiated when it is called or used to assign values to the function pointer. Note: For template functions, the type of the real parameters of the function must be strictly matched when the real parameters of the template type are obtained and instantiated. During this matching process, no default type conversion will be performed. For example, a template has a real parameter T: Template <typename T> int compare (const T & V1, const T & V2) {If (V1> V2) return 1; if (V1 = V2) return 0; Return-1;} when the call is as follows: int main () {short a = 10; int B = 11; compare (, b);} an error is returned: Error: no matching function for call to 'compare (Int &, short Int &) '. If you want to use the default conversion of the internal type, two types of parameters need to be defined in the template function. Template <typename T1, typename T2> int compare (const T1 & V1, const T2 & V2) {If (V1> V2) return 1; if (V1 = V2) return 0; Return-1 ;}===> only two types of conversions are supported: const conversion: the parameter is a const reference or pointer, it can accept references from non-const objects or arguments of pointers. Array or function-to-pointer conversion: An array is a pointer to the first element, and a function argument is a pointer to the function type. Note: the restrictions on these types of conversion are not limited only for the template functions whose types are template type parameters -- converted after instantiation. You can use the template function to assign values to function pointers for initialization. 16.2.2 explicit real parameter template of the function template <typename T1, typename T2, typename T3> T1 compare (const T2 & V1, const T3 & V2) {return V1 + V2 ;} in this example, we cannot determine the type of the returned value. For example, how to determine the return value for a summation function that accepts real parameters of the int short long type? Explicit arguments must be used to call these parameters: int M = 100; Double N = 21.5; long x = sum_1 <long> (m, n ); // specify the return value type as long16.3. Compile the model for normal function calls using the template function. As long as there is a function declaration, the template function must generate an instance during instantiation. Therefore, you must be able to access the function source code. the same is true for class types. A common class type definition. A member function can be declared only in the header file. The function implementation can be placed in the CPP source file. However, when instantiating a member function of the template class, you must access the source code. Different compilers support different processing methods. Two types: 1 contains the compilation model. The source file contains the header file of the template function or template class. Must be supported by the compiler. 2. Compile the model separately. The header file defines the implementation of classes and functions of these templates. In the source file, use the export declarations. 16.4 when using a class, you must specify the type parameters of the template class. However, you can use a non-qualified name of the class template within the scope of the class itself. For example, in the template-class queue <type> definition body, you can directly use queue instead of queue <type>. However, when defining other member functions in the class in vitro, you must explicitly specify the type parameters. -- I don't think it is necessary to save this. It is shown inside and outside the class. The form of a class-1 template member function is as follows: it must start with the keyword template, and the following template parameter table of the class must indicate the scope of the class, class Name + scope operator class name must contain template <class T> return-type queue <t>: Member-name example: template <class type> void queue <type>: Push (const type & item) {cout <"Push:" <item <Endl ;} define a function template with a type parameter named type; return OID; in the scope of the queue <type> class template. Then, the member function name and function parameter list are displayed. The member functions of the class template are instantiated only when they are used by the program. Otherwise, they are not instantiated. The template parameters of the member function are determined by the type of the object involved in calling the class member function. 16.4.2 non-type parameters can be used as template parameters. Take the screen class as an example: Template <int hi, int WID> class screen {public: screen (): screen (Hi * WID, '#'), cursor (0), height (HI), width (WID) {cout <"New screen1: width = "<width <" \ theight = "
The following is the test code.
// C ++ primer plus ...... chapter 15 page490 # include <iostream> # include <string> # include <fstream> # include <sstream> # include <vector> # include <utility> # include <New> # include <functional> using namespace STD; // use list to implement queuetemplate <class type> class queue; Template <class type> ostream & operator <(ostream & OS, const queue <type> & Q ); template <class type> void frd_func (const queue <type> & Q); // Private classtemplate <class type> class queueitem {// public: // template <class T> friend class queue; friend class queue <type>; friend ostream & operator <type> (ostream & OS, const queue <type> & Q); friend void frd_func <type> (const queue <type> & Q ); queueitem (const type & T): item (t), next (0) {} type item; queueitem * Next ;}; template <class type> class queue {public: queue (): Head (0), tail (0) {cout <"Qu EUE constructor "<Endl;} Queue (const queue & Q): Head (0), tail (0) {cout <" queue constructor "<Endl; copy_elems (q );}~ Queue () {cout <"queue destructor" <Endl; destory ();} type & Front () {return head-> item;} const type & Front () const {return head-> item;} void push (const type &); void POP (); bool empty () const {return head = 0 ;} friend ostream & operator <type> (ostream & OS, const queue <type> & Q); friend void frd_func <type> (const queue <type> & Q ); PRIVATE: queueitem <type> * head; queueitem <type> * tail; void destory (); Void copy_elems (const queue <type> &) ;}; // Private functionstemplate <class type> void queue <type >:: destory () {While (! Empty () Pop ();} template <class type> void queue <type >:: copy_elems (const queue <type> & orig) {for (queueitem <type> * P = orig. head; P = p-> next) {push (p-> item );}} // public functions // push one item to the tail of queuetemplate <class type> void queue <type>: Push (const type & item) {cout <"Push \ t" <item <Endl; queueitem <type> * P = new queueitem <type> (item); P-> next = 0; if (empty () Head = tail = P; else {Tai L-> next = P; tail = P ;}} template <class type> void queue <type >:: POP () {queueitem <type> * P = head; head = head-> next; cout <"Pop \ t" <p-> item <Endl; Delete P ;}// operator, friend functiontemplate <class type> ostream & operator <(ostream & OS, const queue <type> & Q) {OS <"<"; queueitem <type> * P; for (P = Q. head; P! = 0; P = p-> next) {OS <p-> item <"" ;} OS <">"; return OS ;} template <class type> void frd_func (const queue <type> & Q) {cout <"FRD func test:" <q. head-> item <Endl;} // ------------------------------------------------------- // template of the real parameter of the non-type parameter <int hi, int WID> class screen {public: screen (screen (): screen (Hi * WID, '#'), cursor (0), height (HI), width (WID) {cout <"New screen1: width = "<width <" \ theight = "