Template i undefined reference (podział programu na pliki)

0

Witam,
mam problem z użyciem szablonów:

//SortowaniePrzezKopcowanie.h
#ifndef SORTOWANIEPRZEZKOPCOWANIE_H
#define SORTOWANIEPRZEZKOPCOWANIE_H

template <typename Typ>
class SortowaniePrzezKopcowanie
{
    public:
        SortowaniePrzezKopcowanie();
        virtual ~SortowaniePrzezKopcowanie();
        void TworzenieKopca(Typ *tab, Typ liczba_elementow, Typ kierunek);
        void RozbieranieKopca (Typ *tab, Typ liczba_elementow, Typ kierunek);
        void Sortowanie(Typ *tab, Typ liczba_elementow, Typ kierunek);
}
//fragment SortowaniePrzezKopcowanie.cpp
template <typename Typ>
void SortowaniePrzezKopcowanie<Typ>::Sortowanie(Typ *tab, Typ liczba_elementow, Typ kierunek)
{
    TworzenieKopca(tab,liczba_elementow, kierunek);
    RozbieranieKopca(tab,liczba_elementow, kierunek);

}
void TemporaryFunction ()
{
    SortowaniePrzezKopcowanie<int> TempObj;
}
//fragment pliku main.cpp
#include "SortowaniePrzezKopcowanie.h"
SortowaniePrzezKopcowanie<int> Sort1;
Sort1.Sortowanie(tab1,StopienZapelnienia[i]*rozmiar_tab-1,1);

Przy wywołaniu metody Sortowanie w main.cpp kompilator wskazuje błąd:
undefined reference to SortowaniePrzezKopcowanie<int>::Sortowanie(int*, int, int)'`

Generalnie postępowałem wg wskazówek na tej stronie:
http://www.codeproject.com/Articles/48575/How-to-define-a-template-class-in-a-h-file-and-imp

wg rozwiązania problemu nr1. Niestety, u mnie występuje powyżej wskazany problem z komplikacją

1

Szablony definicji muszą być widoczne w miejscu użycia, co wyklucza ich przeniesienie do plików .cpp - muszą być w nagłówkach. Możesz co najwyżej podzielić nagłówki na ten z szablonem definicji klasy i na ten z szablonami definicji metod.

0

Czyli jak się chce używać szablonów, to nie można dzielić projektu na pliki nagłówkowe?
Trochę to dla mnie dziwne. Zresztą, wg strony którą podałem, to działa. U mnie jednak nie chce

1

Jak najbardziej można. Ale definicja szablonu musi być widoczna w miejscu użycia. Jeśli jest schowana w innym pliku .cpp to nie jest widoczna¹

¹Możesz konkretyzować szablon dla pewnych typów, ale to tyle.

0
kq napisał(a):

Jak najbardziej można. Ale definicja szablonu musi być widoczna w miejscu użycia.

Czyli w moim przypadku w main.cpp?
Rozumiem więc, że powinienem zdefiniować te metody w pliku main.cpp tak? To rozwiązanie jest jednak bez sensu.

Czy możesz zaproponować sposób, w jaki najlepiej to rozwiązać przy obecnej strukturze plików?

2

Tak jak pisałem, powinny być w nagłówku. W main.cpp nie ma sensu, chyba, że nigdzie poza tym plikiem nie będziesz tego używał.

Max co możesz zrobić to możesz sobie podzielić nagłówki na foo.hpp i foo_impl.hpp (tutaj to co było w .cpp).

0

A jednak udało mi się zostać przy obecnej strukturze

Źródło: https://www.daniweb.com/programming/software-development/threads/143139/c-template-success-methods-in-seperate-cpp-file

Zmieniony kod:

//SortowaniePrzezKopcowanie.h
#ifdef SORTOWANIEPRZEZKOPCOWANIE_H
 
template <typename Typ>
class SortowaniePrzezKopcowanie
{
    public:
        SortowaniePrzezKopcowanie();
        virtual ~SortowaniePrzezKopcowanie();
        void TworzenieKopca(Typ *tab, Typ liczba_elementow, Typ kierunek);
        void RozbieranieKopca (Typ *tab, Typ liczba_elementow, Typ kierunek);
        void Sortowanie(Typ *tab, Typ liczba_elementow, Typ kierunek);
}
#include "SortowaniePrzezKopcowanie.cpp"
#endif
//fragment SortowaniePrzezKopcowanie.cpp
#ifdef SORTOWANIEPRZEZKOPCOWANIE_H
template <typename Typ>
void SortowaniePrzezKopcowanie<Typ>::Sortowanie(Typ *tab, Typ liczba_elementow, Typ kierunek)
{
    TworzenieKopca(tab,liczba_elementow, kierunek);
    RozbieranieKopca(tab,liczba_elementow, kierunek);
 
}
void TemporaryFunction ()
{
    SortowaniePrzezKopcowanie<int> TempObj;
}
#endif

Plik main.cpp bez zmian. Może komuś się przyda. Pozdrawiam :)

2

Przecież to jest to samo co napisałem, tylko zamiast rozszerzenia nagłówka .h czy .hpp masz .cpp.

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