STL: container és template

Fórumok

Van egy vector-om, ami container-eket tartalmaz: pl. vector<set<int>>. Szeretnék egy másik vector-t, amelyik a méreteket tartalmazza (tehát a 0-ik elem a 0-ik set<int> mérete).
Egy lehetőség:

template <class T>
struct Sizer : public unary_function<T,typename T::size_type>
{
  typename T::size_type operator()(const T& x) const
  {
    return x.size();
  }
};

template <class T>
vector<typename T::size_type> SizeVector(const vector<T> &Input)
{
  vector<typename T::size_type> SV;
  transform(Input.begin(), Input.end(), back_inserter(SV), Sizer<T>());
  return SV;
};

Eddig OK. De ha nekem list<set<int>>-em is van akkor újra meg kell írni a rutint ezúttal list-tel.
A kérdésem: megoldható template-tel, hogy ne kelljen minden container típusra megírni a SizeVector rutint?

Hozzászólások

Mi lenne, ha a SizeVector egyből két iterátort kapna bemenő paraméternek vector helyett?

KisKresz

Szerintem a kimenetet is változtatni akarja...

De ha nem, akkor sem feltétlenül kell az iterátor:


template <template <typename U> class T,typename U>
vector<typename U::size_type> SizeVector(const T<U> &Input)
{
  vector<typename U::size_type> SV; 
  transform(Input.begin(), Input.end(), back_inserter(SV), Sizer<U>());
  return SV;
};

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o

Ebben igazad van, bár az új szabványban elmennek a könnyen használhatóság irányába. :)

Viszont ha a kimenő változó típusát is szeretnéd autómatikusan változtatni, akkor az iterátor nem lesz jó (kivéve, ha van benne valami typedef erre...).

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o

Pedig ha az eredeti külső konténer list, akkor lehet értelme, pl.: ha rendszeresen törölgetünk elemeket a közepéről és a törlés után frissíteni akarjuk a méreteket is.

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o

Rögtön 3 verzióm is van, attól függően, hogy hogyan értelmezem a feladatot:
1: tetszőleges konténer<konténer>-ből tetszőleges konténer<egész>-be.
2: tetszőleges konténer<konténer>-ből tetszőleges konténer<size_type>-ba.
3: tetszőleges konténer<konténer>-ből a megfelelő konténer<size_type>-ba.



template <typename V,typename T>
V Size1(const T &Input)
{
  V sv=V();
  transform(Input.begin(), Input.end(), back_inserter(sv), Sizer<typename T::value_type>());
  return sv;
} 

template < template <typename I> class J,template <typename V> class T,typename V>
J<typename V::size_type> Size2(const T<V> &Input)
{
  J<typename V::size_type> sv=J<typename V::size_type>();
  transform(Input.begin(), Input.end(), back_inserter(sv), Sizer<V>());
  return sv;
} 


template <template <typename V> class T, typename V>
T<typename V::size_type> Size3(const T<V> &Input)
{
  T<typename V::size_type> sv=T<typename V::size_type>();
  transform(Input.begin(), Input.end(), back_inserter(sv), Sizer<V>());
  return sv;
} 



int main ()
{
...

  vector<set<int>::size_type> sv1=Size1< vector<set<int>::size_type> >(vec);

  vector<set<int>::size_type> sv2=Size2< vector >(vec);

  vector<set<int>::size_type> sv3=Size3(vec);
...
}

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o

Köszönöm mindenkinek a hozzászólását!

tr3w: erre a template-ben template struktúrára nem gondoltam, de majd kiróbálom. Az eredményt fixen vector-ban gondoltam, függetlenül a bemenő container-től.

KisKresz: nem int-eket, hanem set<int>-eket tennék list-be. Például egy adott helyen tartózkodók ID-jeit. Így időrendben megnézhető, hogy hogyan alakult az aktuális létszám.

"nem int-eket, hanem set<int>-eket tennék list-be. Például egy adott helyen tartózkodók ID-jeit. Így időrendben megnézhető, hogy hogyan alakult az aktuális létszám"

Azt arra írtam, ha a visszatérési érték típusa is változna a bemenő container típusára.

KisKresz

Természetesen nem az input struktúrája döntené el az output-ét, hanem a felhasználás módja. Tehát az output akkor lehetne set<int>, ha nem érdekelne az adatok sorrendje (egy idősor esetén ez nem így van).
Ennyire általános módszerre nem gondoltam, mint tr3w 2. verziója.