szablon+funkcja zaprzyjazniona

0

Hi. Zaczne moze od przykladowego kodu:

template <class T>
class stos{
      struct wezel{
             T* wskobj;
             wezel* next;
             wezel():wskobj(NULL),next(NULL){}
      };
      friend void funk (void);
};

template <class T>
void funk(void)
{
     //stos<T>::wezel *bla;
}

Mamy szablon klasy, w nim zagniezdzona inna klase( a wlaciwie strukture, ale to nieistotne) i funkcje zaprzyjazniona. Moje pytanie brzmi: jak w tej funkcji zaprzyjaznionej stworzyc obiekt klasy zagniezdzonej? Zakomentowany sposob znalazlem w Pasji C++ J.Grebosza. Dla zwyklych klas jest w porzadku, ale przy szablonach nie dziala, dostaje blad:`bla' undeclared (first use this function)
kompilowalem w dev c++ 4.9.9.2 i gcc pod linuxem. Probowalem rowniez kompilowac przyklad dolaczony do Pasji C++ dotyczacy m.in. tego tematu( dostepny tu: http://chall.ifj.edu.pl/~grebosz/pasja_przyklady_wrzes2004.zip przykl_12_03_str300.cpp), ten sam blad. Wg autora, program ten dziala pod gcc i VC++(niestety nie mam mozliwosci sprawdzenia VC++). Czy ktos ma jakis pomysl co z tym zrobic?
pozdrawiam, dzieki

0

Po pierwsze to przyklady w PAsji dzialaja chyba tylko u Autora ;P

A po drugie to jest funkcja zaprzyjazniona do klasy szablonowej, a wiec i ona powinna byc szablonem(pisze z glowy, a wiec nie jestem pewny co do poprawnosci :] ) :


friend void funkcja<class T>(void);

Ale w wersji deva 4.9.9.2 powinien juz byc mingw z kompilatorem w wersji 3.4.2, a wiec zamiast

 <class T> 

sprobuj <type T>

0

Oczywiscie masz racje w 2pkt, przeoczylem ten fragment, we wlasciwym kodzie jest to zawarte. Wiec powiedzmy ze przyklad wyglada tak:

template <typename T> class stos;
template <typename T> void funk(stos<T> &b);
template <typename T>
class stos{
      struct wezel{
             T* wskobj;
             wezel* next;
             wezel():wskobj(NULL),next(NULL){}
      };
      friend void funk <> (stos<T> &b);
};

template <typename T>
void funk(stos<T> &b)
{
     stos<T>::wezel *bla;
     
}

Jednak nadal nie rozwiazuje to problemu deklaracji zmiennej. type nie dziala. Czy piszac <type T> miales na mysli <typename T> ? czym to sie wlasciwie rozni od class?

0

W BCB 6.0 PE to co napisales dziala (znaczy sie kompiluje).

//DOPISANE:
podany przyklad, tez sie kompiluje (i nawet cos wypisuje) bez wiekszych zmian (zamiana

#include "osoba.h"

na typedef string osoba;

)
0

Tak mialem na mysliu typename :)

Dla przyzwoitosci sciagnalem ten przyklad i skompilowalem za pomoca identycznego kompilatora i za cholere nie wiem jak mu sie go udalo skompilowac :/ .

Ja szczerze mowiac niegdy tego w ten sposob nie robilem, ale nad tym chwile posiedze, bo mnie problem zainteresowal :]

0
foflik napisał(a)

W BCB 6.0 PE to co napisales dziala (znaczy sie kompiluje).

jakbys mogl to spojrzy sie w naglowek pliku zrodlowego z ksiazki ;P Ja tego autora nie doceniam, ale z ta opinia sie calkowicie zgadzam.

I on jest wlasnie wykladowca akademickim :]

0

Zainstalowalem dev c++ 4... i skompilowal, bez bledow. hmm wiec wychodzi na to, ze to wina nowego dev?? dziwne... w kazdym badz razie dziekuje za pomoc. Z opinia na temat VC++ trudno sie nie zgodzic:> (bo mysle ze o ta czesc naglowka chodzilo...) zdarzylo mi sie przerabiac prosty program z vc na gcc. troche zabawy bylo:/

0

Wracajac do twojego pytania, to zamiana class na typename przy szablonach jest zmiana czysto kosmetyczna :] Nadal mozna uzywac class i kompilatory sie nie rzucaja.

Ale program w zadnym nowszym porzadnym kompilatorze nie pojdzie, ponownie cos pozmieniali ze standardami, i juz. Ale np. w main spokojnie mozesz wywolac stos<int>::wezel :d , ale w ogóle stosowanie funkcji zaprzyjaznionych przy szablonach jest sadomasochistycznym pomyslem ;P

0

O wywolaniu w main() wiem:> Piszesz zeby nie stosowac funkcji zaprzyjaznionych przy szablonach...Jak bys zrobil w takim razie przeciazenie operatora<< ? Do tego wlasnie miala sluzyc ta funkcja zaprzyjazniona, elementem stosu(wezla) ma byc dowolny obiekt, zeby go poprawnie wyswietlic potrzebne jest przeciazenie tego operatora. nie moge tego zrobic w funkcji skladowej, bo pierwszym argumentem przeciazenia jest obiekt innej klasy(ostream). stad funkcja zaprzyjazniona... jestem otwarty na lepsze pomysly:>

0

No nie to jest fakt, w tym przypadku potrzebujesz funkcji zaprzyjaznionej.

Ja przewaznie nie zagniezdzam klas ;P a wiec jest mi latwiej. A po drugie zawsze mozna zrobic metode, ktora bedzie zwracala po kolei elementi, takie cos jak metoda pop(), top() w STL. Jezeli nie musisz tworzyc sam tego stosu, to wykorzystal gotowe elementy STL'a. Jest ona wydajniejsza, a to co chcesz zrobic zrobisz na iteratorach ;P
Wiecej informacji na stronie domowej STL.

Szablony to jest jedyny element jezyka, ktory nie ma ujednoliconego standardu, i dlatego kod z gcc 2.9.6 nie dziala na gcc 3.3.3, a dzial juz znowu na gcc 3.4.2. Nie wiem jak ty, ale ja tego za nic na swiecie nie rozumiem :d

0

Szczerze mowiac ja tez to na poczatku zrobilem bez zagniezdzenia, pozniej natnalem sie na ten przyklad Grebosza i stwierdzilem ze sie pobawie:) Stos musze tworzyc sam - to zadanie na uczelnie. STL jeszcze nie znam, ale juz sie z tego lecze:>
hmm wlasciwie patrzac na c++, szablony zostaly dosyc niedawno wprowadzone, miejmy nadzieje ze wkrotce sie to ustabilizuje...
dzieki raz jeszcze za pomoc
pozdrawiam

0

Hmmm, czy WIDZISZ co kompilator ci pokazuje w ostrzeżeniach??
Dodaj flagi -W -Wall

Rodzaje "zaprzyjaźnień":
http://publib.boulder.ibm.com/infocenter/macxhelp/index.jsp?topic=/com.ibm.vacpp6m.doc/language/ref/clrc16friends_and_templates.htm

Temat podobny do:
http://forum.tweak.pl/index.php?showtopic=128064&st=0&p=1396630&
Tak naprawdę kompilator nie wie co TY chcesz zrobić, ale mówic ci co możesz zrobić...
Przerzuć deklarację funkcji zaprzyjaźnionej PRZED deklaracje klasy, jeżeli oczywiście to jest to co chcesz uzyskać...

[sorki, nie mam kompilatora pod ręką... dziwne rzeczy mogą wyjść podczas używania obiektów tej klasy... w innych przypadkach taka deklaracja oczywiście może być poprawna... wszelkie bluzgi >> nul]

1 użytkowników online, w tym zalogowanych: 0, gości: 1