Recently used C + + templates, feel very powerful, just write up need to master a bit of skill. Most templates are written directly to the. h header file, and some people say that the reason for this is that the template does not support sub-compilation, but the previous compiler does not support the template well enough, but it is now perfectly possible.
Environment:
Win7 32 flagship edition, VS2010 SP1
1. Normal function template
Define.h file
1 template<typename t>2 T GetString (int value);
Define.cpp file
1#include"define.h"2 3Template<typename t>4T getstring<t> (intvalue)5 {6 returnT (value);7 }8 9 //Partial localizationTenTemplate<> One stringgetstring<string> (intvalue) A { - Charpsz[ +] = {0}; -Itoa (value, Psz,Ten); the return string(psz); - } - - //Partial localization +Template<> -Wstring getstring<wstring> (intvalue) + { Awchar_t psz[ +] = {0}; at_itow (value, Psz,Ten); - returnwstring (psz); -}
If we directly include Define.h, using the getstring<int> (100) function call, is not used, will produce a link error, why? We have set the general implementation of the function template, but it is not instantiated as a real function, since it is not a function, the compiler certainly does not generate code, so there will be link errors; The most important thing to solve this problem is to instantiate the function template so that it becomes a real function. The first approach is to use the above-biased method, such as the wstring of the string and the type, because it has already been written, so not much; the second approach:
1 #define Template_get_string (t) template T getstring<t> (int value); 2 template_get_string (int)// function template instantiation 3// If you want to export this function in a DLL, We can do this . 4int getstring<int> (int value);
2. Class template
Define.h file
1Template<typename t>2 classA3 {4 Public:5 A ()6 {7 InitValue ();8 }9 Ten voidInitValue (); One A intM_nvalue; -};
Define.cpp file
1Template<typename t>2A<t>:: A ()3 {4 InitValue ();5 }6 7Template<>8 voida<string>:: InitValue ()9 {TenM_nvalue = -; One } A -Template<> - voida<int>:: InitValue () the { -M_nvalue = $; - } - + //instantiation of class templates - Template +a<int>;
3. member function template
Define.h file
1 class B 2 {3public:4 template<typename t>5 T Get ( int index); 6 };
Define.cpp file
1 //member function template partial localization2Template<>3 Doubleb::get<Double> (intindex)4 {5 return 2.1;6 }7 8 //member function template partial localization9Template<>Ten intb::get<int><int> (intindex) One { A return 1; - } -</int> the //If Class B is a database wrapper class, we can use this method of invocation to get the fields in a record in a database - - b b; -b.get<int> (1);//gets the value of the first field in the current record and translates to the int type +b.get<Double> (2)//gets the value of the second field in the current record and converts to a double type
4. Bind the type to some data
Sometimes we need to bind the type to some data, for example, we typically associate a string with a function (register), and then create an object from a string.
1 class A {2public:3 Static return New A ();} 4 };
And then like this:
1 instance::register ("A", a::create); 2 * a = Instance::create ("a");
Binding with strings, not very convenient, if the string is misspelled, there will be no hint at the entire compile time, and the string is no code automatically prompt, so the error rate is greatly increased, of course, you can copy/paste; If we can bind a type to data and get the relevant data by type, One is the type has the Code automatic prompt (the general spelling first several characters can complete the entire input), promptly your own spelling error, did not define this type, the compiler compiles the error.
1typedefvoid* (*createcallback) ();//Create a pointer to a function2 classInstance {3 Public:4 /** Registration5 * Types of @T bindings6 * @callback object creation function7 */8template<classT>9 Static voidRegister (Createcallback callback) {TenM_map.insert (Std::make_pair (typedefine<t>, callback)); One } A - /** Create Objects - * @T Types of objects created the * Objects created @return - */ -template<classT> - Statict*Create () { +Std::map<typedefineindifiry, Createcallback>::iterator iter = M_map.find (typedefine<t>); - return(t*) iter->second (); + } A at Private: -template<classT> - Static voidTypedefine () {} - -typedefvoid(*Typedefineindifiry) (); - StaticStd::map<typedefineindifiry, createcallback>M_map; in }; -Std::map<instance::typedefineindifiry, createcallback> Instance::m_map;
Next we use it:
1 instance::register<a>((createcallback) a::create); 2 * A = instance::create<a> ();
C + + templates