[C++] 2 pytania dotyczące specjalizowanej klasy szablonowej


(Quentin) #1

Witam!

Mam dwa pytania dotyczące specjalizowanej klasy szablonowej.

Załóżmy, że mam w programie specjalizowaną klasę szablonową. Oto przykładowy kod:

template <class typ>class X { };

([alex]) #2
  1. Ponieważ klasa jest zadeklarowana jako wzorzec, to deklaracja konstruktora, destruktora czy tez innej składowej w ciele klasy już ma zadeklarowana przynależność do tego wzorca razem z parametrami.

  2. Coś nie tak zrozumiałeś/zrobiłeś z tymi funkcjami/metodami wyspecjalizowanymi. Kompilator zawsze próbuje skorzystać z wyspecjalizowanej funkcji, jeżeli niema takiej to dopiero próbuje korzystać z tej standardowej we wzorcu.


(Quentin) #3

2.

#include using namespace std;

([alex]) #4

Czy pamiętasz ze w C/C++ deklaracja funkcji musi wystąpić przed pierwszym użyciem?

wystarczy przed main dać:

void fun(int,int);void fun(char,char); [/code]

Co do pierwszego:[code=php]templatetypename Typ class X{   public:   void F1() { Typ tmp; cout"funkcja F "tmpendl; }   void XTyp::F2() { Typ tmp; cout"funkcja F "tmpendl; }  }; Metody F1 oraz F2 są absolutnie identyczne.

(Quentin) #5

1.

Wiem, że są identyczne ale co to ma do mojego pytania... Nie wiem czy mnie zrozumiałeś, ale podkreślę dla pewności:

  1. Sorry, powinienem dać cytat:

Nie wiem, może coś się zmieniło, bo książka jest z 2003 roku wydana przed wprowadzeniem C++03... I właśnie może niektóre kompilatory na to pozwolą. Ja się chciałem zapytać czego nie są tak "rozumne" przy specjalizowanych wersjach klas... Zresztą pisałem o tym w 1-szym poście.


([alex]) #6

Poza klasa jest tylko jedna możliwość, a mianowicie ten drugi wariant.

Niektóre kompilatory potrafią poprawnie obsłużyć:

int n;cinn;double tb[n]; [/code]Ale to nie jest poprawny kod C++.

Generalną zasadę C/C++ nie powinno się łamac, chodzi o "każda funkcja powinna być zadeklarowana przed pierwszym wywołaniem".

(Quentin) #7

Wiem, wiem, wiem... Nie wiem czy mi się uda to wytłumaczyć o co mi chodzi, bo nie rozumiesz mnie chyba, a ta rzecz jest pokręcona. Chodzi mi o nazwę konstruktora w klasie szablonowej specjalizowanej. Wiadomo, że taka klasa ma w nazwie parametry:

template <> //<-- chodzi o funkcję szablonową specj.class Xint //przy założeniu, że szablon ma postać: template  class X { /*...*/ };{ }; [/code]



I teraz w tej klasie specjalizowanej można nazwać destruktor i kompilator dwojako:




[code=php]Xint();X();//...~Xint();X(); 



A po za klasą (z operatorem zakresu) można tylko tak:





Xint::X();//...Xint::~Xint();Xint::~X(); [/code]



Jak widać - [b]nie da się tylko czegoś takiego napisać[/b]:




[code=php]Xint::Xint(); 





Co jest dziwne, bo ta sama forma przy destruktorze jest OK. Jak mówiłem testuję to Comeau C++, który jest zgodny ze standardem, więc nie wiem dlaczego tak się dzieje... Np. Visual 2008 pozwala na wszystkie zapisy, ale o nim to szkoda gadać.

([alex]) #8

X::X(); // to nie jest poprawnie zadeklarowany konstruktor

X::~X(); // to nie jest poprawnie zadeklarowany destruktor

X::X(); // to jest poprawnie zadeklarowany konstruktor

X::~X(); // to jest poprawnie zadeklarowany destruktor

Te niepoprawne deklaracje pod g++ jednak działają, jak na zewnątrz tak i wewnątrz klasy.

Jeżeli kompilator nie przyjmie obie niepoprawne konstrukcje to będzie to zgodne ze standardem.

Jeżeli kompilator przyjmie obie niepoprawne konstrukcje to będzie to rozszerzenie standardu (co prawda nie wiem poco komu takie rozszerzenie).

Jeżeli kompilator przyjmie tylko jedną z tych niepoprawnych konstrukcji to jest to dziwadło a nie kompilator.


(Quentin) #9

Temat z przed miesiąca, ale odpowiem odnośnie problemu z funkcjami specjalizowanymi, bo dobry ze mnie człowiek, i może komuś kiedyś się to przyda, jak będzie szukał w Google :smiley:

#include using namespace std;