First steps
To handle templates, you need four things:
-- Typename keyword: it shows that the type that follows is abstract (or template parameter depends on a parameter template) and that it should be taken into account only when it instantiates.
-- Keyword template: it indicates that the symbol (structure, class, position) who will monitor takes parameters templates. It is
written directly after the keyword template settings templates (preceded by the keyword typename, struct, class or type basis depending on the type of template parameter expected) brackets, followed by the symbol written normally. Make sure to separate the rafters (Closing) so that it should not be confused with the operator>>.
In this example we'll see
-- How to encode a class template
-- How to encode a function template
-- How to encode an operator template
In this example symbols settings to take just one parameter template, but the approach remains similar settings with several
templates.
Example:
Code:
template <typename T1, typename T2, ... >
Type_Typename_t my_function (param1_t p1, param2_t p2, ...)
{ ... }
Template <typename T1, typename T2, ... >
Class my_class_t (... );
Template <typename T1, typename T2, ... >
My_struct_t struct (... );
-- The operator::: it allows access to the fields (in particular types) and static methods of a class or a structure. It is not specific to the templates (it applies to classes and structures in general and namespaces). You can see a bit like the '/' directories. Thus std:: vector <int>:: const_iterator means that I go to type const_iterator, stored in the class <int> vector itself encoded in the namespace std.
We will define our own class of vehicle to illustrate what has been said. Of course in practice be used directly class std:: vector of the STL.
Code:
# include <iostream>
# include <cstdlib>
# include <ostream>
template <typename T>
class my_vector_t {
protected:
unsigned size;
T * data;
public:
my_vector_t (unsigned size0 = 0, const T & x0 = T( )): size (size0),
data ((T *) malloc (sizeof (T) * size0)) { for (unsigned i = 0; i <size; ++ i) data [i] = x0; }
~ my_vector_t () { free (data); }
inline unsigned size () const {return size;}
inline const T & Operator [] (unsigned i) const {
if (i> = size ())
throw: return data [i];}
inline T & operator [] (unsigned i ) {
If (i> = size ())
throw: return data [i]; } }
template <typename T>
std:: ostream & operator <<(std:: ostream & out, const my_vector_t <T> & v)
{ unsigned n = v.size ();
out << "[";
for (unsigned i = 0; i <n; ++ i)
out <<v [i] << '';
out << ']';
return out; }
template <typename T>
void write (const my_vector_t <T> & v)
{ unsigned n = v.size ();
std::cout << "[";
for (unsigned i = 0; i <n; ++ i)
std:: cout << v[i] << ' '; std:: cout << ']'; }
int main ()
{ my_vector_t <int> v(5), v [0] = 6;
v [1] = 2;
v [2] = 3;
v [3] = 4;
v [4] = 8;
write <int> (v)
std:: cout <<std :: endl;
write (v);
std:: cout <<v <<std::endl;
return 0; }
At the completion:
Code:
[6 2 3 4 8] [6 2 3 4 8] [6 2 3 4 8]
Anything that is in "early my_vector_t class" and "end my_vector_t class" could be moved to a header (eg my_vector.hpp) can be included by the main program.
Bookmarks