• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Funkcja szablonowa w klasie

Object Storage Arubacloud
0 głosów
364 wizyt
pytanie zadane 24 listopada 2018 w C i C++ przez Poczprogramista123 Bywalec (2,900 p.)

Witam, moje pytanie brzmi jak zdefiniowac funkcje szablonowa ktora znajduje sie w klasie w pliku .h

///plik naglowkowy
class a
{
template<typename t>
void cos(t);
}

///plik cpp

/// i jak mam taka funkcje zdefiniowac

Z gory dzieki.

3 odpowiedzi

+2 głosów
odpowiedź 24 listopada 2018 przez criss Mędrzec (172,590 p.)

Definicja nie może znajdować się w pliku źródłowym (*.cpp), o ile jawnie nie podasz jakie instancje takiego szablonu mają być skompilowane (tutaj: jakie typy mają być podstawione za `t`).

Definicja, niezależnie czy w .cpp czy w .h, może wyglądać tak:

template<typename t>
void a::cos(t) { ; }

Jawna konkretyzacja (tak to nazwijmy), powinna się znajdować po definicji:

template void a::cos<int>(int);
template void a::cos<float>(float);
// itd...
komentarz 25 listopada 2018 przez Poczprogramista123 Bywalec (2,900 p.)
Super dzieki za odp juz czaje
+1 głos
odpowiedź 24 listopada 2018 przez j23 Mędrzec (194,920 p.)
class a
{
    template<typename T>
    void cos(T && arg)
    {
        /* tu implementacja */
    }
};

 

komentarz 25 listopada 2018 przez RafalS VIP (122,820 p.)
Takie cos w pliku cpp nie zadziala. No chyba że będziesz korzystal z tej implementacji tylko w tym samym pliku cpp.

Kompilator musi wiedzieć jakie specjalizacje stworzyc. Nie jest w stanie tego okreslic jesli specjalizacje te sa w innym pliku, kompilowanym oddzielnie juz po kompilacji pliku z definicja szablonu.
komentarz 25 listopada 2018 przez j23 Mędrzec (194,920 p.)

Dostał odpowiedź na pytanie "jak zdefiniowac funkcje szablonowa ktora znajduje sie w klasie w pliku .h".

komentarz 25 listopada 2018 przez RafalS VIP (122,820 p.)
Racja, sprzeczne pytanie :D. W kodzie sugerował, że chce mieć definicje w .cpp a w temacie ze w .h :D
0 głosów
odpowiedź 25 listopada 2018 przez RafalS VIP (122,820 p.)
edycja 25 listopada 2018 przez RafalS

Przedmówcy wyjaśnili już jak rozwiązać problem to ja może napisze 2 zdania czemu taki problem występuje i czemu nie ma nic złego w definiowaniu szablonu funkcji w pliku .h (.hpp).

Dla jasności:

  • Deklaracja szablonu funkcji:
    template <typename T>
    void fun(T x);
  • Definicja szablonu funkcji:

    template <typename T>
    void fun(T x) {}

Podkreślam. Są to szablony funkcji a nie funkcje szablonowe. Te twory same w sobie nie są funkcjami. Są przepisem jak stworzyć funkcje.

Przepis ten jest wykorzystywany do wygenerowania funkcji w dwóch przypadkach:

  • niejawnie - gdy ktoś zawoła funkcję
    fun(1);
  • jawnie:

    template fun(int x);
    

Żeby kompilator mógł wygenerować funkcję z szablonu - definicja tego szablonu musi być kompilowana razem z kodem generującym instacje funkcji:

template <typename T>
void fun(T x){}

template void fun(double x){}
int main(){
   fun(1);
}

Jeśli rozdzielisz deklaracje z definicją to kompilator najpierw sobie skompiluje szablon. A potem gdy będziesz próbował wywołać funkcję poleci błąd linkera, bo wywołanie zgadza sie z deklaracją szablonu, ale funkcja nie została wygnerowana z tego szablonu. Kompilator jest krótkowzroczny. Jak kompiluje jeden plik szablon.cpp to nie widzi jakie funkcje, które mozna wygenerowac z tego szablonu będą później potrzebne.

Co zrobić, jak żyć?

Nie przejmować się tylko wrzucić definicje do pliku h. Czemu tak można (czemu to nie łamie one-definition-rule):

There can be more than one definition in a program, as long as each definition appears in a different translation unit, of each of the following: class type, enumeration type, inline function with external linkage inline variable with external linkage (since C++17), class template, non-static function template, static data member of a class template, member function of a class template, as long as all of the following is true:
...

Trzema kropkami sie generalnie nie przejmujemy. Kilka oczywistych oczywistosci (np, ze definicje musza byc takie same) i wyjątków (np, ze linkujemy z tym samym jezykiem).

Można też tak jak koledzy wspomnieli jawnie wygenerować odpowiednie instacje w pliku szablon.cpp:

template <typename T>
void fun(T x){}

template void fun(int x);

Wtedy definicja może zostać w pliku .cpp, ale trzeba pamiętać, żeby jawnie wygenerowac wszystkie użyte gdzieś indziej instancje (tak, bardzo łatwo o tym zapomnieć, a czasem wręcz się nie da - gdy piszesz biblioteke :P)

EDIT: jako ciekawostka - istnieje różnica pomiędzy:

//A.h
class A {
    template <typename T>
    void fun(T x);
};
//wciaz A.h
template<typename T>
void A::fun(T x) {}

a

class A {
	template <typename T>
	void fun(T x) {}
};

W drugim przypadku fun jest niejawnie zdeklarowna jako inline

komentarz 25 listopada 2018 przez Poczprogramista123 Bywalec (2,900 p.)
Wow super odpowiedz wielkie dzieki. Juz wszystkie watpliwosci zostaly rozwiane. Tylko przyokazji dopytam by juz miec jasnosc. Czy mozna nadawac wartosci poczatkowe atrybutom w ciele klasy? Jak to jest bo jak stawialem pierwsze kroki z obiektowka to Zelent mowil ze tylko w konstruktorze mozna to robic i zostalo mi to do dzis a jak przegladam sobie czyjes kody to widze ze odrazy nadaja wartosci w ciele klasy.
komentarz 25 listopada 2018 przez RafalS VIP (122,820 p.)

Tak. Od C++11 można tak pisać. W kursie Zelenta nie było bo tam nie było C++11. Źródlo:

https://en.cppreference.com/w/cpp/language/data_members

class A{
   int a = 10;
}

 

komentarz 25 listopada 2018 przez Poczprogramista123 Bywalec (2,900 p.)
Super dzieki

Podobne pytania

0 głosów
1 odpowiedź 268 wizyt
pytanie zadane 12 lipca 2022 w C i C++ przez cpp_lover Początkujący (290 p.)
0 głosów
1 odpowiedź 286 wizyt
pytanie zadane 7 kwietnia 2020 w C i C++ przez amtrax Dyskutant (9,630 p.)
–1 głos
0 odpowiedzi 88 wizyt
pytanie zadane 22 października 2018 w C i C++ przez niezalogowany

92,556 zapytań

141,404 odpowiedzi

319,561 komentarzy

61,942 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...