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?
- 1149 megtekintés
Hozzászólások
Mi lenne, ha a SizeVector egyből két iterátort kapna bemenő paraméternek vector helyett?
KisKresz
- A hozzászóláshoz be kell jelentkezni
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
- A hozzászóláshoz be kell jelentkezni
Azért írtam az iterátorokat, mert érzésem szerint az illene bele az STL filozófiájába.
KisKresz
- A hozzászóláshoz be kell jelentkezni
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
- A hozzászóláshoz be kell jelentkezni
Ő tudja, mi kell neki, én azért alaposan elgondolkoznék azon, valóban list-ben akarok-e tárolni valamilyen egészeket. :-)
KisKresz
- A hozzászóláshoz be kell jelentkezni
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
- A hozzászóláshoz be kell jelentkezni
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
- A hozzászóláshoz be kell jelentkezni
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.
- A hozzászóláshoz be kell jelentkezni
"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
- A hozzászóláshoz be kell jelentkezni
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.
- A hozzászóláshoz be kell jelentkezni
Akkor neked tényleg az iterátoros megoldás kell. Esetleg az amit KisKresz-nek válaszban írtam...
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni