[c++] O co chodzi kompilatorowi ?

0

Mój problem polega na tym, że wprowadziłem (typedef Node<K,V> Node;) i zamieniłem wszędzie w kodzie Node<K,V> na Node tylko, że pojawił się błąd gdy jakaś metoda zwraca Node** wcześniej cały kod się kompilował i działał poprawnie, a typedef będzie mi potrzebny przy rozwijaniu projektu i zastanawiam się dlaczego kompilator krzyczy mi przy implementacji metody Node** BSTreeAVL<K,V>::FindNode(const K& key)
takie coś:

expected constructor, destructor, or type conversion before '*' token

taki sam rezultat jest przy metodzie Node** BSTreeAVL<K,V>::MinMaxNode(Node** n, bool m) ( przy tej lini)

mam taki kod:

template<class K, class V>
	class BSTreeAVL
	{
	    typedef Node<K,V> Node; // to dodałem

	    // cos ...

	    public:
		BSTreeAVL();
		~BSTreeAVL();

		// cos ...

	    private:
		int count;
		Node* main_node;

		Node** FindNode(const K& key);
		Node** MinMaxNode(Node** n, bool m);
		void DeleteNode(Node** n);
	};

i mam jeszcze taki kod:

template<class K, class V>
    	Node** BSTreeAVL<K,V>::FindNode(const K& key) // tutaj krzyczy
    	{
    	    Node** nd = &main_node;

    	    while(*nd != 0 && (*nd)->getKey() != key)    	    
		nd = key < (*nd)->getKey() ? (*nd)->getLeft() : (*nd)->getRight();
			
	    if (*nd == 0) throw NotFoundKeyException("Klucz nie istnieje");  // to można pominąć
	    return nd;                                                    // tutaj można zwracać NULL lub 0
    	}

 template<class K, class V>
    	Node** BSTreeAVL<K,V>::MinMaxNode(Node** n, bool m) // tutaj też
    	{
    	    Node** nd = n;
    	    if (m)
    		while(*(*nd)->getLeft() != 0)
    			nd = (*nd)->getLeft();
    	    else
    		while(*(*nd)->getRight() != 0)
    			nd = (*nd)->getRight();
    	    return nd;
    	}

proszę o pomoc w rozwiązaniu problemu :)

0

Trudne co ?

0

Skąd kompilator ma wiedzieć, co to jest Node? Musisz podać typ razem z nazwą klasy, w której zrobiłeś typedef, czyli "BSTreeAVL<K,V>::Node".

0

całkiem logidzne :) dzięki za odpowiedź :)

0

Przykro mi, ale po sprawdzeniu tego w domu (byłem na wyjeździe) okazuje się, że to rozwiązanie nie działa, efekt jest taki sam jak wcześniej. Nic nie pomogło, błąd musi być jednak innej natury:

template<class K, class V>
            BSTreeAVL<K,V>::Node** BSTreeAVL<K,V>::FindNode(const K& key) // tutaj nadal krzyczy
            {
                Node** nd = &main_node;

                while(*nd != 0 && (*nd)->getKey() != key)                
                nd = key < (*nd)->getKey() ? (*nd)->getLeft() : (*nd)->getRight();
                        
            if (*nd == 0) throw NotFoundKeyException("Klucz nie istnieje");
            return nd;
            }
0

Do tego, co podał Fanael, dodaj jeszcze typename, czyli:

typename BSTreeAVL<K,V>::Node** BSTreeAVL<K,V>::FindNode(const K& key) { ... }

typename BSTreeAVL<K,V>::Node** BSTreeAVL<K,V>::MinMaxNode(typename BSTreeAVL<K,V>::Node** n, bool m) { ... }

typedef Node<K,V> Node; 

Takie nadawanie nazw nie jest dobrym pomysłem... Zresztą jeśli metody definiujesz masz poza definicją klasy, niewiele zyskujesz, a nawet tracisz na czytelności. Bo zamiast:

Node<K,V>

musisz dać:

typename BSTreeAVL<K,V>::Node 
0

Niestety, tego kodu nadal nie łyka
może i trochę zaciemnia, ale chce wrzucić jeszcze klasę iteratora, która też byłaby templatem i przeskakiwała by po Nodach, a nie będę mógł zrobić tak:

 
TreeIterator<Node<K,V>> iterator ;

sądziłem, że z typedefem da rade to dość prosto zrobić, a jednak okazuje się, że nie :/

0

Łyknąć to on musi, ale tak się zastanawiam, czy przypadkiem nie dałeś definicji metod w oddzielnym pliku CPP, który dołączyłeś do projektu w sposób typowy - add to project itp. Jeśli tak, to przenieś je do pliku nagłówkowego.

Oczywiście to, co pisałem wcześniej, też musisz zrobić ;-)

0

to wiem, wiem że tak trzeba, bo inaczej w ogóle nie tworzy kodu metod z tempaltów

tylko zrobiłem trochę inny myk, czyli że zrobiłem definicje metod w innym pliku, ale na koniec pliku BSTreeAVL.h dałem

// ostatnia linia
#include BSTreeAVL.hpp 

P.S. .hpp to tak sobie nazwałem żeby wiedzieć potem, że to jakby część nagłówka tylko taka z definicjami

zanim zacząłem używać typedefa działało

0

Po co takie dziwne zabiegi? Zrób to w jednym pliku i prawdopodobnie problem się rozwiąże.

0

taki zabieg był tylko po to żeby sam projekt był bardziej przejrzysty i pliki nie za długie żeby nie szukać, takie bardziej "smart" ;) ale jak widać kompilator nie tego nie lubi ;P

dzięki zadziałało

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