STL y templates

STL – templates

templates.h

#ifndef _TEMPLATES_H_
#define _TEMPLATES_H_
 template <typename T> class Vector {
T* v;
int sz;
public:
Vector (int s) { v = new T [sz = s]; }
~Vector () { if (v) delete[] v; }
//vector "circular"
T& operator[] (int i) const { return v[i%sz];}
int get_size() { return sz; }
bool operator< (const Vector&) const;
};
  template <typename T> bool Vector<T>::operator < (const Vector &v2) const
{
//si todos los componentes son menores -> el vector es menor.
for (int i=0; i<sz; i++)
if (v[i]>=v2[i]) return false;
return true;
}
 //especializacion de la template.
template <> class Vector<char> {
char* v;
int sz;
public:
Vector (int s) { v = new char[sz = s]; }
~Vector () { if (v) delete[] v; }
//vector "circular"
const char& operator[] (int i) const { return v[i%sz]; }
int get_size() { return sz; }
/*
Remarcar lo del CONST que si lo saco a operator[], no anda el
operator <
*/
bool operator< (const Vector& v2) const
{ //si todos los componentes son menores -> el vector es menor.
for (int i=0; i<sz; i++)
if (v[i]>=v2[i]) return false;
return true;
}
};
 #endif // _TEMPLATES_H_

templates.cpp

#include "templates.h"
 #include <iostream>
 #include <vector>
 #include <string>
  typedef Vector<char> VecChar;
 /*
 Se hace para ahorrarn escritura o si lo hago el el .h
 le hago usar una clase cuando en realidad es un template.
 */
   typedef std::vector<int> stdVecInt;
 typedef std::string stdString;
  int main (void)
 {
 // Usamos cout para escribir menos
 using std::cout;
  /*****************************************************************/
 /*        PARTE DE TEMPLATES.                                         */
  Vector<int>        int_vector (10);
 Vector<float>    float_vector(10);
 VecChar            char_vector (10);
    for (int i=0; i<10; i++)
 {
 int_vector[i]=i;
 cout<<int_vector[i]<<"\n";
 }
    /*****************************************************************/
  /****************************************************************/
 /*            PARTE DE STL                                        */
 cout<<"Parte de la STL\n";
  stdVecInt v(3); //me reserva 3 lugares cuado lo contruye
  v[0] = 5;
 v[1] = 2;
 v[2] = 7;
  cout<<"tamaño antes de push_back: "<<v.capacity()<<"\n";
 v.push_back(10);  //tambien existe el pop_back
 cout<<"tamaño despues de push_back: "<<v.capacity()<<"\n";
 //verificamos que push_back dobla la capacidad actual.
  /*
 Hay que tener en cuenta que tengo que instanciar el iterador
 adecuado para recorrer al contenedor. Para no tener problemas
 con esto, las clases de la STL incluyen a los iteradores como
 subClases y uno tiene que instanciar los iteradores contenidos
 en la clase, es decir no puedo instanciar un iterador de lista
 para recorrer un Vector.
 */
  stdVecInt::iterator iFirst = v.begin();
 //me devuelve un iterador del tipo std::vector<int>::iterator.
 stdVecInt::iterator iLast  = v.end();
 //El iLast apunta a un elemento despues del final del vector
 stdVecInt::iterator iV = v.begin();
  iV+=1; //tienen sobrecargado el operador += (iV apuntando a 2);
  /* El insertar sobre el primer elemento me hace que sean
 inválidos todos los iteradores que estén apuntando
 a elemento a la "derecha" del punto de inserción.
 En nuestro caso el iLast quedaría inválido.*/
 v.insert(iFirst,456);
  v.insert(iLast,20);  //en realidad no estoy insertando en
 //el ultimo. (resultado no garantizado);
 iLast = v.end();
  //    iLast=v.erase(iLast);  //estoy queriendo borrar una memoria
 //que nunca inicialice (excepcion).
  iLast=v.erase(--iLast); //solucion correcta.
  /*
 Tener muy en cuenta que si se produce realocacion, ningun
 iterador es válido.
 */
  while (iV != iLast)
 cout << *iV++ << " ";
 //primero se desreferencia y despues se incrementa.
  cout<<"\n";
  /* POSIBILIDADES QUE OFRECE LA BASIC_STRING    */
  stdString str1("012345"), str2("6789");
  cout<<"\nPARTE DE LA STRING\n";
  str1.append(str2); //existen 6 sobrecargadas de append.
  str2="456"; //operador = sobrecargado.
  char cadena[]="HOLA";
 str2.append(cadena);  //append de cadena literal.
  cout<<str2.c_str()<<"\n"; //devuelve una string de c cte.
  /*comparacion contra literal*/
 stdString s1("TORTITA");
  if (s1=="TORTITA")
 cout<<"Es una tortita\n";
 else cout<<"Es otra cosa\n";
  /*Concatenacion*/
 stdString s2= s1+str2;
 cout<<s2.c_str()<<"\n";
  return 0;
  }