"Klasa" does not name a type

Odpowiedz Nowy wątek
2016-05-07 23:15
0

Z góry muszę napomnieć, iż jestem bardzo początkującym programistą. Mam za zadanie napisać szablon drzewa binarnego i chciałem dodać do niego funkcję przeszukującą to drzewo ale podczas kompilacji wyskakuje mi taki oto błąd 'error: TreeNote does not name a type' i mam pytanie jaki jest tutaj błąd? Czy muszę użyć jakiegoś operatora zakresu w kontekście tej klasy wbudowanej i jakiego ? Przepraszam jeśli jest to jakieś banalne pytanie ale przeszukałem już trochę forów i nie mogłem znaleźć rozwiązania mojego problemu.

plik tmptree.h

#ifndef TMPTREE_H
#define TMPTREE_H

template <class T> class TmpTree
{
    public:
        class TreeNode
        {
            public:
            T Data;
            TreeNode* Parent;
            TreeNode* RightSon;
            TreeNode* LeftSon;
            TreeNode(T& data);

        };
        TreeNode* Root = NULL;
        void Insert (T& newData);
        TreeNode* Search();

    protected:

    private:

};

#endif // TMPTREE_H

plik tmptree.cpp

#include "tmptree.h"

template <class T>  TreeNode* Search(TreeNode* start, T sData)
{
    if(start->Data = sData)
    {
        return start;
    }
    else if(sData < start->Data && start->LeftSon != NULL)
    {
        return Search(start->LeftSon , sData);
    }
    else if(start->RightSon != NULL)
    {
        return Search(start->RightSon , sData);
    }
    return NULL;
}

Pozostało 580 znaków

2016-05-07 23:16
2016-05-07 23:19
kq
4

Jeśli początkujący to zapraszam tutaj: Newbie

Problemy:

  1. Szablony muszą być widoczne w pełni w miejscu użycia (z wyjątkami na razie dla ciebie nieistotnymi), więc implementacja metody nie może być w .cpp
  2. w pliku tmptree.cpp definiujesz szablon wolnej funkcji Search, a nie metody klasy (zapomniałeś o operatorze zakresu)
  3. nawet gdybyś nie zapomniał, musiałbyś w pełni zdefinioawać zwracany typ przez funkcję (TmpTree<T>::TreeNode*)

czy ja wiem, szablony trochę nie pasują do Newbie - twonek 2016-05-07 23:54
W sumie fakt. Ale błędy (wolna funkcja zamiast funkcji klasy) jednak na to wskazują. Meh, nie wiem ;) - kq 2016-05-07 23:57
Możliwe, że dostał strzępy kodu i nie wie jak go poskładać. - carlosmay 2016-05-08 00:17

Pozostało 580 znaków

2016-05-08 14:59
0

Z tą wolną funkcją to ta próbowałem jakoś to zmienić żeby zadziałało, a jak wrzucałem kod to nie poprawiłem. Dzięki za pomoc. Jeśli można to chcę zadać jeszcze jedno pytanie.
Otóż chcę zadeklarować specjalizację metody w szablonie klasy no i robię to w taki sposób

template <typename T> class TmpTree
{
    public:
        class TreeNode
        {
            public:
            T Data;
            TreeNode* Parent;
            TreeNode* RightSon;
            TreeNode* LeftSon;
            TreeNode(T& data);

        };
        TreeNode* Root = NULL;

        void PrintData(T& data)
        {

            std::cout << T << std::endl;
        }

    protected:

    private:

};
        template<> void TmpTree<Album>::PrintData(Album& data);

        template<> void TmpTree<Album>::PrintData(Album& data)
        {
            std::cout << "Autor albumu: "<<data.Author <<std::endl;
            std::cout << "Tytul albumu: " << data.Title << std::endl;
            std::cout << "Rok wydania albumu: " << data.PubliDate << std::endl;
        } 

Błąd to multiple definition of `TmpTree<album>::PrintData(Album&)

Znalazłem gdzieś że kod w tej postaci jest poprawny. Ogólny przykład:

template <typename T>
struct Test {
    void print_type() {
        cout << "Type is: " << typeid(T).name() << "\n";
    }
};

template<>
void Test<int>::print_type();

template<>
void Test<int>::print_type() {
    cout << "It's int\n";
} 

Jaka jest różnica w moim kodzie, a tym powyżej że kompilator tego nie przepuszcza, lub jak inaczej można taką metodę zadeklarować?

Pozostało 580 znaków

2016-05-08 15:01
kq
1

Możesz wyspecjalizować całą klasę, albo samą funkcję (tylko dla w pełni skonkretyzowanych klas). Ciekawe.


edytowany 2x, ostatnio: kq, 2016-05-08 16:02

Pozostało 580 znaków

2016-05-08 15:43
0

A czy muszę wtedy definiować wszystkie metody od początku dla klasy wyspecjalizowanej, czy jeśli ich nie zdefiniuje to zostaną użyte te z szablony klasy ogólnej ? Taka specjalizacja częściowa o ile istnieje coś takiego.

Pozostało 580 znaków

2016-05-08 15:49
1
template<> void TmpTree<Album>::PrintData(Album& data);

        template<> void TmpTree<Album>::PrintData(Album& data)
        {}

..multiple definition of 'TmpTree<album>::PrintData(Album&)'

template <typename T> class TmpTree
{
    public:
        class TreeNode
        {
            public:
            T Data;
            TreeNode* Parent;
            TreeNode* RightSon;
            TreeNode* LeftSon;
            TreeNode(T& data);

        };
        TreeNode* Root = NULL;

        void PrintData(T& data)
        {

            std::cout << T << std::endl;
        }
 //+
    template<> void PrintData(Album& data);
    protected:

    private:

};
//-    template<> void TmpTree<Album>::PrintData(Album& data);

        template<> void TmpTree<Album>::PrintData(Album& data)
        {
            std::cout << "Autor albumu: "<<data.Author <<std::endl;
            std::cout << "Tytul albumu: " << data.Title << std::endl;
            std::cout << "Rok wydania albumu: " << data.PubliDate << std::endl;
        } 

Definiujesz metody wyspecjalizowane analogicznie jakbyś definiował funkcje do zwyczajnej klasy dla kilku rodzajów zmiennej użytej jako parametr np. class TmpTree { func(T&); func(int&); func(char&); albo func(int&) const; } po czym tworzysz ciała TmpTree::func(int&) { } itd.
W definicji klasy wpisujesz nazwe funkcji jaką chcesz wyspecjalizować z podaniem rodzaju zmiennej dla jakiej chcesz to zrobić. Z tą różnicą że przed definicją i deklaracją ciała musisz użyć słówka: template
Przy tworzeniu ciała zamiast TmpTree<t>::PrintData(T& data) { ciało.. } używasz wyspecjalizowanego typu TmpTree<album>::PrintData(&Album data) { ciało } ale również rozpoczynasz słówkiem template mówiącym że to funkcja wyspecjalizowana więc:

template<> void TmpTree<Album>::PrintData(Album &data) { ciało.. }

EDIT: dziwne bo porada działała w BCB (na mojej klasie) sprawdziłem też stacoverflow podobne wzory, a w MinGW dla analogicznie wyspecjalizowanej klasy:
"explicit specialization in non namspace scope" Wygląda na to że powyższą porade można sobie wsadzić.
http://en.cppreference.com/w/[...]guage/template_specialization
http://wazniak.mimuw.edu.pl/i[...]PP/Wyk%C5%82ad_3:_Szablony_II

edytowany 11x, ostatnio: stasinek, 2016-05-08 17:31

Pozostało 580 znaków

2016-05-08 17:04
0

Po przerobieniu kodu tak jak wyżej mi mi napisałeś (mój kod wygląda dokładnie tak samo) i usunięciu tej ogólnej metody void PrintData(T& data) bo inaczej dostaję komunikat o tym że nie mogę przeładować tej funkcji

||=== Build: Debug in albums_collection (compiler: GNU GCC Compiler) ===|
C:\Users\Mateusz\Documents\Sort Tester\albums_collection\tmptree.h|142|error: explicit specialization in non-namespace scope 'class TmpTree<T>'|
C:\Users\Mateusz\Documents\Sort Tester\albums_collection\tmptree.h||In instantiation of 'class TmpTree<Album>':|
C:\Users\Mateusz\Documents\Sort Tester\albums_collection\tmptree.h|281|required from here|
C:\Users\Mateusz\Documents\Sort Tester\albums_collection\tmptree.h|142|error: 'void TmpTree<T>::PrintData(Album&) [with T = Album]' cannot be overloaded|
C:\Users\Mateusz\Documents\Sort Tester\albums_collection\tmptree.h|88|error: with 'void TmpTree<T>::PrintData(T&) [with T = Album]'|
||=== Build failed: 3 error(s), 2 warning(s) (0 minute(s), 0 second(s)) ===|

kompilator wskazuje na linię
template<> void PrintData(Album& data);
w definicji klasy i wyrzuca
error: explicit specialization in non-namespace scope 'class TmpTree<T>'
Czy źle zrozumiałem to co mi napisałeś i po prostu muszę tutaj jeszcze coś poprawić ?

edytowany 1x, ostatnio: smoothy, 2016-05-08 17:09
da sie, zrozumiałeś dobrze, problem jest skomplikowany a ja też się ucze, jest specjalizacja wzorców klasy jako całości, specjalizacja funkcji i zwykłe przeciążanie ogólnie z ~8 kombinacji np. template<> void PrintData<Album>(Albums& data); analogicznie ciało template<> void TmpTree<T>::PrintData<Album>(Albums& data) i wszelkie pochodne void TmpTree<Album>::PrintData<Album>(Albums& data) ale też nie działa.. :) - stasinek 2016-05-08 18:10
@stasinek wyjaśniłem problem niżej a Ty dalej jakieś cuda na kiju wymyślasz? A problem wcale nie jest skompilowany. - pingwindyktator 2016-05-08 18:21
@pingwindyktator baardzo pomocna odpowiedz.. nie ma co, daruj sobie - stasinek 2016-05-08 18:40
@stasinek dokładnie wyjaśniłem w czym leży problem, nie rozumiem Twojej frustracji. - pingwindyktator 2016-05-08 18:41
@pingwindyktator Jako iż jestem raczej początkujący nie do końca rozumiem to co napisałeś. Czy mógłbyś to wyjaśnić jakoś (jeśli się da) prościej ? Albo może przykład jakby to należało zrobić? - smoothy 2016-05-08 19:00

Pozostało 580 znaków

2016-05-08 17:48
1

Prawdopodobnie robisz explicit specjalizacje funkcji w klasie. Nie można tak. Dlaczego? Cholera wie ;D


Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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