[ grabber @ 17.03.2010. 22:34 ] @
pozdrav,

radim nesto, tj pokusavam malo provjezbat genericke funkcije na primjeru kopiranja sa uslovom, copy if, evo sta sam uradio, nekako mi je sve logicno, ali na oznacenoj liniji kompajler javlja gresku:

Code:
#include<iterator>
#include<vector>
#include<iostream>
using namespace std;

template <typename In, typename Out, typename Pred>
void copy_if(In pocetak, In kraj, Out prema, Pred op)
{
       while( pocetak != kraj)
       {
               if(op(*pocetak))
               {
                       *prema = *pocetak;
                       prema++;
               }
               pocetak++;
       }
       return prema;
}

template <typename t, typename br>
t provjera(br podatak)
{
             if (podatak>0) return 1;
             else return 0;              
}
              
int main()
{
       vector<int> a;
       vector<int> b;
       int x;
       while ( cin >> x )
              a.push_back(x);
       copy_if(a.begin(),a.end(),back_inserter(b),provjera); //******************ovdje je greska
       cout<<"Stari niz:\n";
       int i;
       for(i=0;i<a.size();i++)
                              cout<<a[i];
       cout<<"\nNovi niz:\n";
       for(i=0;i<b.size();i++)
                              cout<<b[i];
                              
       system("pause");
       return 0;
}
[ Mihajlo Cvetanović @ 17.03.2010. 22:58 ] @
Template funkcije i template klase ne mogu da budu parametri ičega jer oni zapravo ne postoje. Oni su samo opis onog što bi postojalo kada bi se template funkcija (ili klasa) potpuno instancirala. Drugim rečima, umesto provjera stavi recimo provjera<int,int>. To će ti onda proći, ali posle mi se kompajler žalio da funkcija copy_if, deklarisana da ne vraća ništa, pokušava da vrati nešto sa return. Ali to je već drugi padež.
[ grabber @ 18.03.2010. 01:42 ] @
Code:
#include<list>
#include<iterator>
#include<vector>
#include<iostream>
using namespace std;

template <typename In, typename Out, typename Pred>
void copy_if(In pocetak, In kraj, Out prema, Pred op)
{
       while( pocetak != kraj)
       {
               if(op(*pocetak))
               {
                       *prema = *pocetak;
                       prema++;
               }
               pocetak++;
       }
       
}
int provjera(int podatak)
{
             if (podatak>0) return 1;
             else return 0;              
}
              
int main()
{
       vector<int> a;
       vector<int> b;
       int x;
       while ( cin >> x )
              a.push_back(x);
       copy_if(a.begin(),a.end(),back_inserter(b),provjera);
       cout<<"Stari niz:\n";
       int i;
       for(i=0;i<a.size();i++)
                              cout<<a[i];
       cout<<"\nNovi niz:\n";
       for(i=0;i<b.size();i++)
                              cout<<b[i];
                              
       system("pause");
       return 0;
}


eto ovaj kod radi fino... ali ova funkcija provjera mi malo pravi problem, jer opet njoj sam morao reci da radi sa podacima tipa INT, a program je trebao biti univerzalan za sve tipove podataka, brojcane naravno... postoji li nacin da to preuredim, da radi provjeru i ako je u pocetku vector (a) postavljen kao vektor tipa double, ili float? Jer program bi trebao demonstrirati mogucnost upotrebe jedne gen. funkcije za razlicite kontejnere i razlicite tipove podataka...
[ Mihajlo Cvetanović @ 18.03.2010. 08:16 ] @
copy_if i jeste univerzalan u smislu da prima bilo kakvu funkciju s jednim parametrom, koja vraća bilo šta što se može interpretirati kao bool. Zamislimo da je funkcija provjera zapravo template i da radiš sa std::string umesto sa int. U funkciji provjera ti gledaš da je parametar veći od nule, ali takvo poređenje nema smisla raditi sa stringom. To znači da ti treba posebna funkcija za ako radiš sa stringovima. I posebna za svaku drugu klasu ili strukturu. Ako već korisnik mora funkciji copy_if da obezbedi odgovarajuću posebnu funkciju kao četvrti parametar onda to i ne treba da bude template.