Szablony klas, nagłówki i include

0

Potrzebuję zrobić szablon klasy, żeby nie robić wielu identycznych klas różniących się typem danych.

Utworzyłem dwie testowe klasy:

szablontest1.h

#ifndef SZABLONTEST1_H
#define SZABLONTEST1_H

template <class T>
class SzablonTest1
{
private:
    T Buf[10];

public:
    SzablonTest1();
    void Wczytaj(int N, T Val);
    T Pobierz(int N);
};

#endif // SZABLONTEST1_H

szablontest1.cpp

#include "szablontest1.h"

template <class T>
SzablonTest1<T>::SzablonTest1()
{
}

template <class T>
void SzablonTest1<T>::Wczytaj(int N, T Val)
{
    Buf[N] = Val;
}

template <class T>
T SzablonTest1<T>::Pobierz(int N)
{
    return Buf[N];
}

szablontest2.h

#ifndef SZABLONTEST2_H
#define SZABLONTEST2_H

template <class T>
class SzablonTest2
{
private:
    T Buf[10];

public:
    SzablonTest2()
    {
    }

    void Wczytaj(int N, T Val)
    {
        Buf[N] = Val;
    }

    T Pobierz(int N)
    {
        return Buf[N];
    }
};

#endif // SZABLONTEST2_H

szablontest2.cpp

#include "szablontest2.h"

Wiadomo, że prawidłowo, to w pliku .h podaje się pola klasy i deklaracje metod, a w pliku .cpp implementuje się metody. Używam QtCreator z kompilatorem MinGW. Dla zwykłych klas nie ma problemu, natomiast do szablonu jest problem z kompilacją.

Próbuję skompilować taki kod.

    SzablonTest1<int> ST1;
    ST1.Wczytaj(0, 27);
    cout << ST1.Pobierz(0) << endl;

    SzablonTest2<int> ST2;
    ST2.Wczytaj(0, 27);
    cout << ST2.Pobierz(0) << endl;

Jeżeli w pliku zrobię include szablontest1.h i szablontest2.h, to przy metodach z SzablonTest1 pojawia się błąd "undefined reference to `SzablonTest1<int>::SzablonTest1()'", podobnie dla wszystkich 3 metod.

Jak zrobię include szablontest1.cpp i szablontest2.h, co jest co najmniej dziwne, bo prawidłowo, to się dołącza pliki .h, a nie .cpp, to program kompiluje się i działa poprawnie.

Gdzie jest błąd i jak prawidłowo utworzyć szablon klasy SzablonTest1 tak, że po include pliku .h program kompiluje się i działa poprawnie?

0

Bo generalnie nie da się tak robić z szablonami.
http://www.parashift.com/c++-faq-lite/separate-template-fn-defn-from-decl-export-keyword.html
Niby jest słowo kluczowe które miało to załatwić, ale chyba nie wszystkie kompilatory to implementują. Musisz wepchnać cały kod do nagłówka i nie kombinowac :P

0

szablon zawsze pchaj w nagłówek wraz z implementacją. niestety taki fail z szablonami.

0

By​ć może C++17 rozwiąże to modułami. Na razie najlepsze co możesz zrobić to dwa pliki nagłówkowe¹ (i wybrać konwencję, np. szablon_fwd.h i szablon.h lub szablon.h i szablon_impl.h) i rozbić Twój szablon na deklaracje i definicje tak jakbyś to robił z plikami .cpp. Ale w miejscu użycia i tak będziesz potrzebował pełnego kodu szablonu.

¹ tak poleca np. Herb Sutter: http://herbsutter.com/gotw/_101/

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