Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Pitanje u vezi template-a

[es] :: C/C++ programiranje :: Pitanje u vezi template-a

[ Pregleda: 3590 | Odgovora: 11 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

Predrag Damnjanovic
Predrag Damnjanovic
Nis, Srbija

Član broj: 141
Poruke: 1305
*.6.EUnet.yu

Sajt: www.mycity.rs


+1 Profil

icon Pitanje u vezi template-a25.04.2003. u 23:03 - pre 232 meseci
Imam jednu template klasu, sto nije mnogo ni bitno.
Jedna funkcija te klase bi trebala da kreira jedan novi objekat, te iste klase, ali sa drugim tipom (ovako : new ista_klasa<tip>;).
Problem je sto bi ja toj funkciji u run-time modu trebao nekako da prosledim tip koji zelim, dakle u trenutku kompajliranja se ne zna tip.
Da li je moguce to da se izvede?

P.S. Imam resenje da fja samo vrati referencu pointera, pa ti sam kreiras novi objekat, kakav zelis, i dodelis ga pointeru. Ali me interesuje da li mora tako?
 
Odgovor na temu

Dragi Tata
Malo ispod Kanade

Član broj: 1958
Poruke: 3906
199.171.112.*



+6 Profil

icon Re: Pitanje u vezi template-a25.04.2003. u 23:36 - pre 232 meseci
Neće moći. Šabloni su compile-time mehanizam i svi njihovi parametri moraju biti poznati u vreme kompilacije.
 
Odgovor na temu

Rapaic Rajko
Bgd

Član broj: 4105
Poruke: 802
*.beg.sezampro.yu



+62 Profil

icon Re: Pitanje u vezi template-a27.04.2003. u 11:36 - pre 232 meseci
E da; ponovo se doticemo one price o early i late binding-u.
Kao sto sam vec nekom prilikom ranije rekao, template-i su veoma mocni, ali za neki totalni OOP - prilicno beskorisni...
Ne zelim da otvaram diskusiju, samo komentarisem, onako usput.
Pozdrav

Rajko
 
Odgovor na temu

*Andra
Andrija Petrovic
Beograd

Član broj: 11014
Poruke: 2
*.yubc.net



Profil

icon Re: Pitanje u vezi template-a04.06.2003. u 11:18 - pre 230 meseci
Citat:
Predrag Damnjanovic:
Imam jednu template klasu, sto nije mnogo ni bitno.
Jedna funkcija te klase bi trebala da kreira jedan novi objekat, te iste klase, ali sa drugim tipom (ovako : new ista_klasa<tip>;).
Problem je sto bi ja toj funkciji u run-time modu trebao nekako da prosledim tip koji zelim, dakle u trenutku kompajliranja se ne zna tip.
Da li je moguce to da se izvede?


Template upravo i sluzi da se sve ono sto se ne zna u compile-time-u prosledi kao parametar template-a.
Sam koncept template-a je mnogo flexibilniji nego sto izgleda na prvi pogled.
Naime, u okviru template koji ima proizvoljan broj parametara mozes imati jos funkcija/metoda koje su takodje parametrizovane svaka na svoj nacin.

Dalje, postavlja se pitanje kakva ova funkcija treba da bude. S obzirom da ti treba funkcija koja vraca/kreira objekte istog tipa kao sto je i klasa sama, u pitanju ti je neka <factory> funkcija. U klasicnom C++/class design-u, pozeljno je takve funkcije napraviti kao staticke metode. Medjutim, kod template-a ce ti "ubacivanje" takve funkcije u template klasu (proizvodjenje ove funkcije u metodu klase) samo praviti probleme - kasnije, u koriscenju te funkcije.

Primer:

template <typename T> class A
{
public:
template <typename U> static /*static moze, ali ne mora*/ A<U>& Create()
{
return *(new A<U>);
}
};

Kako sad pozivati metodu Create()?
Ako je metoda bila static, primer sa greskom:

A<int> a = A::Create<int>();

ovako bi bilo u klasicnom, class-based C++-u. Medjutim, sa template-ima imas problem, jer ono A:: ne moze tek tako - mora i to A da bude navedeno sa nekim tipom kao parametrom, a taj tip ti uopste nije trebao u ovom slucaju, cak i ne igra nikakvu ulogu!
Dakle, mora da se "lupi" neki tip
Primer bez greske:

A<int> a = A<void>::Create<int>();
Dakle, imas onaj npr. void koji je tu tek zato da se template "raspertla".

Znaci, najbolje je da ti ova funkcija bude globalna funkcija, van klase:

template <typename T> class A
{
};

template <typename U> static /*static moze, ali ne mora*/ A<U>& Create()
{
return *(new A<U>);
}

E, ovo te vodi dalje u probleme Factory-ja: ako imas funkciju koja kreira objekte "spolja", sta ce ti onda public konstruktor za klasu A?
A ako stavis taj konstruktor da bude private/protected, onda treba da f-ju Create proglasis friend-om klase A.
Ni ovo ti nije lose.

A sta ako hoces da objekti klase A<neki_tip> mogu da kreiraju objekte klase A<neki_drugi_tip> ? Tada je Create metoda (ne-staticka) klase A, i sama klasa A postaje sama sebi factory klasa, sto ti je malo overkill za klasu A. Bolje da napravis posebnu klasu AFactory koja ce ti praviti objekte klase A<bilo_koji_tip>.

I tako dalje, i tako dalje, smorio sam.... ;)

Citat:
P.S. Imam resenje da fja samo vrati referencu pointera, pa ti sam kreiras novi objekat, kakav zelis, i dodelis ga pointeru. Ali me interesuje da li mora tako?


Ovaj P.S. bas i nisam razumeo, mene bi takvo resenje bolelo...
 
Odgovor na temu

*Andra
Andrija Petrovic
Beograd

Član broj: 11014
Poruke: 2
*.yubc.net



Profil

icon Re: Pitanje u vezi template-a04.06.2003. u 11:23 - pre 230 meseci
Napisao sam ti dinosauruski odgovor, a tom prilikom prevideo da ti hoces u run-time-u da prosledis tip.
Ako je tako, reci kako ce to da se desi (daj taj deo koda sto u run-time-u prosledjuje tip), to me bas interesuje....
 
Odgovor na temu

Reljam
Relja Markovic
San Francisco

Član broj: 531
Poruke: 1793
*.client.attbi.com



+18 Profil

icon Re: Pitanje u vezi template-a04.06.2003. u 11:37 - pre 230 meseci
Mislim da ne postoji elegantan nacin da se ovo uradi u standardnom C++u. Ako te interesuje MC++, mozes da pogledas reflection, ali sumnjam da je to praktican odgovor na tvoje pitanje.

Ovo vec zavisi od tvojih klasa, ali da li ih je moguce tako preraditi da umesto templateova imas nekoliko izvedenih klasa? Onda bi mogao da koristis nesto kao:

virtual Base *ConstructNew();

Pri cemu bi naravno tvoj objekat znao koj tip da napravi i vrati.
 
Odgovor na temu

leka
Dejan Lekić
senior software engineer, 3Developers
Ltd.
London, UK

Član broj: 234
Poruke: 2534
*.racasse.se

Sajt: dejan.lekic.org


+2 Profil

icon Re: Pitanje u vezi template-a04.06.2003. u 12:27 - pre 230 meseci
Ja sam siguran da ce Peca da izadje sa nekim resenjem.
Dejan Lekic
software engineer, MySQL/PgSQL DBA, sysadmin
 
Odgovor na temu

Predrag Damnjanovic
Predrag Damnjanovic
Nis, Srbija

Član broj: 141
Poruke: 1305
*.dial.InfoSky.Net

Sajt: www.mycity.rs


+1 Profil

icon Re: Pitanje u vezi template-a04.06.2003. u 16:08 - pre 230 meseci
Zasto vadite teme iz naftalina :)

Elem, resenje je da nema resenja!

Citat:

P.S. Imam resenje da fja samo vrati referencu pointera, pa ti sam kreiras novi objekat, kakav zelis, i dodelis ga pointeru. Ali me interesuje da li mora tako?

Cak ni ovo ne radi, jer mi se 'podatak' pretvara u bazni tip.
Na primer:
Code:

klasa<int> obj1;
obj1.niz_pointer(0) = new klasa<char>;
obj1.niz(0).vrednost(); // vraca int, a ne char

To je zato sto se izvrsava funkcija bazne klase, koja vraca int.
Kada bi ga pozvao sa:
Code:

( (klasa<char>) obj1.niz(0) ).vrednost();

mozda bi radilo (nisam probao), ali je resenje sux.

Elem, posto mora da se navodi tip ispred, napravio sam funkciju koja vraca void*, pa ti posle taj pointer pretvoris u koji hoces:
Code:

*(char *)obj1.vp(0) = 'a';


mada, ni to nije resenje, ali drugacije ne moze, jer se template klase ne kompajliraju u run-time modu :)
 
Odgovor na temu

mipko

Član broj: 11015
Poruke: 109
*.yubc.net



Profil

icon Re: Pitanje u vezi template-a08.06.2003. u 20:55 - pre 230 meseci
Heheheee moj prethodni odgovor je otisao u smece :) A i bio je bas onako bez veze - ruku na srce.

Dobro, evo resenja :

U pitanju je kombinacija TypeLista i GenScatterHierarchy. Realizovano je preko template template parametara ,template rekurzije i specijalizacije template-a.

Resenje je rogobatno posto se pristup funkciji koja Predragu treba vrsi na ruzan nacin. No, postoji mnogo elegantniji nacin i mogu ga prikazati ukoliko vas bude ovaj odgovor zainteresovao.

Code:

#include <iostream>
#pragma hdrstop

using namespace std;

class NullType{};


template <class T, class U> 
class TypeList {
     typedef T Head;
     typedef U Tail;
};


#define TYPELIST_1(T1) TypeList<T1, NullType>
#define TYPELIST_2(T1, T2) TypeList<T1, TYPELIST_1(T2) >
#define TYPELIST_3(T1, T2, T3) TypeList<T1, TYPELIST_2(T2, T3) >

//ovo ptosirujte dalje koliko vam treba parametara - TYPELIST_N

template <class Tlist, template <class> class Unit> 
class GenScatterHierarchy;

template <class T1, class T2, template <class> class Unit>
class GenScatterHierarchy <TypeList<T1, T2>, Unit> :
    public GenScatterHierarchy <T1, Unit>
    , public GenScatterHierarchy<T2, Unit>
{
    typedef TypeList<T1, T2> TList;
    typedef GenScatterHierarchy<T1, Unit> LeftBase;
    typedef GenScatterHierarchy<T2, Unit> RightBase;
};

template <class AtomicType, template <class> class Unit>
class GenScatterHierarchy : public Unit<AtomicType> 
{
    typedef Unit<AtomicType> LeftBase;
};

template <template<class> class Unit>
class GenScatterHierarchy<NullType, Unit>
{
};

template <class T>
class Holder
{
public :
    T value_;
    T* create() {new T;};
};

typedef GenScatterHierarchy<TYPELIST_3(int, char, float), Holder> Info;


int main(){
    Info obj;
    

//ovo se moze izvesti mnogo lepse  
    (static_cast<Holder<int>&>(obj)).value_ = 100;    
//ovo takodje - bez static_cast
    int *I = (static_cast<Holder<int>&>(obj)).create();
    int i = (static_cast<Holder<int>&>(obj)).value_;
    *I = i;
    cout << i<<endl << "*I = "<< *I <<endl;
             delete I;
    return 0;
};


vrlo lako se primenjuje na druge tipove (user classes)

pozdrav
Mirko
 
Odgovor na temu

Dragi Tata
Malo ispod Kanade

Član broj: 1958
Poruke: 3906
199.171.112.*



+6 Profil

icon Re: Pitanje u vezi template-a09.06.2003. u 19:16 - pre 230 meseci
Pa i ovo je compile-time rešenje, a Peca je eksplicitno naveo da mu je potreban run-time mehanizam.
 
Odgovor na temu

sspasic
Sasa Spasic

Član broj: 3261
Poruke: 175
*.medianis.net

Jabber: sspasic@elitesecurity.org
ICQ: 35454521


Profil

icon Re: Pitanje u vezi template-a09.06.2003. u 22:41 - pre 230 meseci
Naravno, nema resenja, ali zato problem koji pokusavas ovim da resis
(sta god on bio) verovatno ima.
Resenje je u tome sto od tacke gde se u vreme izvrsenja prosledjuje tip
i kreira objekat moras da predjes na apstraktne klase.

Code:

#include <iostream>

class ApstraktnaFabrika;

class ApstraktniKontejner {
public:
    virtual ~ApstraktniKontejner() {}
    virtual void Print(std::ostream &out) = 0;
    virtual ApstraktniKontejner *Kreiraj(ApstraktnaFabrika *fabrika) = 0;
};

template<typename T>
class Kontejner : public ApstraktniKontejner {
public:
    Kontejner(T val = 0) : Val_(val) {}
    virtual ~Kontejner() {}

    void Print(std::ostream &out) { out << Val_; }
    ApstraktniKontejner *Kreiraj(ApstraktnaFabrika *fabrika);

private:
    T Val_;
};

template<>
void Kontejner<int>::Print(std::ostream &out) { out << "int:" << Val_; }

template<>
void Kontejner<bool>::Print(std::ostream &out) { out << "bool:" << Val_; }

template<>
void Kontejner<double>::Print(std::ostream &out) { out << "double:" << Val_; }

class ApstraktnaFabrika {
public:
    virtual ~ApstraktnaFabrika() {}
    virtual ApstraktniKontejner *Kreiraj() = 0;
};

template<typename T>
class Fabrika : public ApstraktnaFabrika {
public:
    virtual ~Fabrika() {}
    ApstraktniKontejner *Kreiraj() { return new Kontejner<T>(); }
};

template<typename T>
ApstraktniKontejner *Kontejner<T>::Kreiraj(ApstraktnaFabrika *fabrika)
{
    return fabrika->Kreiraj();
}

Fabrika<int> IntFabrika;
Fabrika<bool> BoolFabrika;
Fabrika<double> DoubleFabrika;

ApstraktnaFabrika *fabrike[] = { &IntFabrika, &BoolFabrika, &DoubleFabrika };

int main()
{
    std::cout << "0-int, 1-bool, 2-double" << std::endl;
    int tip;
    std::cin >> tip;

    Kontejner<int> int_kontejner(5);
    ApstraktniKontejner *drugi = int_kontejner.Kreiraj(fabrike[tip]);
    drugi->Print(std::cout);
    std::cout << std::endl;
    delete drugi;

    return 0;
}



Mana koliko volis:
1. jednog trenutka izgubis informaciju o tipu posto si presao na apstraktne klase
2. U vreme kompajliranja moras da imas konacan skup tipova za koje kontejner moze da se koristi
3. Problem je kako iz objekta kreatora inicijalizovati novi objekat na osnovu vrednosti iz starog. Ovde mogu da se koriste double dispatch fazoni ili vec neki drugi nacin. Ovo nisam stavio u primer.
 
Odgovor na temu

mipko

Član broj: 11015
Poruke: 109
*.yubc.net



Profil

icon Re: Pitanje u vezi template-a10.06.2003. u 15:50 - pre 230 meseci
Citat:
Dragi Tata:
Pa i ovo je compile-time rešenje, a Peca je eksplicitno naveo da mu je potreban run-time mehanizam.


ne slazem se uopste sa time. razmisli jos malo !
 
Odgovor na temu

[es] :: C/C++ programiranje :: Pitanje u vezi template-a

[ Pregleda: 3590 | Odgovora: 11 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.