PDA

View Full Version : [C++] template


riemann_01
23-06-2006, 16:37
Salve a tutti!
Ho creato un programma generico per la gestione di una pila.
Quando tento di compilare il codice sorgente ricevo il seguente messaggio: $ g++ -o stack stack.cc
stack.h:42: warning: friend declaration ‘bool operator==(const stack<T>&, const stack<T>&)’ declares a non-template function
stack.h:42: warning: (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here) -Wno-non-template-friend disables this warning
/tmp/cc9tKuCS.o: In function `main':stack.cc:(.text+0x8f): undefined reference to `operator==(stack<int> const&, stack<int> const&)'
collect2: ld returned 1 exit status

Perche' un warning del genere? Di che tipo di errore si tratta?

Riporto, per completezza, i files d'intestazione e prova.

// file stack.h

#include <exception>
#include <iostream>
using namespace std;

// exception classes
class bad_size {};
class empty {};
class full {};

template <class T>
class stack {
public:
// ctors
explicit stack(unsigned int size) throw(bad_alloc, bad_size)
: top(EMPTY), dim(size)
{
if(size <= 0)
throw new bad_size();
elem = new T[dim];
}
stack(const stack<T> &s) throw(bad_alloc);
// dtor
~stack() { delete []elem; }
// insert
void push(const T &a) throw(full);
// remove
T& pop() throw(empty);
// reset
void reset() { top = EMPTY; }
// check state
bool isFull() const { return (top == dim - 1); }
bool isEmpty() const { return (top == EMPTY); }
// print
void print() const;
// index of last element
unsigned int get_top() const { return top; }
// size of stack
unsigned int get_dim() const { return dim; }
// operator overloading
friend bool operator==(const stack<T> &s1, const stack<T> &s2);
stack<T>& operator=(const stack &s);

protected:
enum {EMPTY = -1};
T *elem;
unsigned int dim, top;
};

template <class T>
stack<T>::stack(const stack<T> &s) throw(bad_alloc)
{
dim = s.dim;
top = s.top;
elem = new T[dim];
for(int i = 0; i <= top; ++i)
elem[i] = s.elem[i];
}

template <class T>
void stack<T>::push(const T& a) throw(full)
{
if(isFull())
throw new full();
else
elem[++top] = a;
}

template <class T>
T& stack<T>::pop() throw(empty)
{
if(isEmpty())
throw new empty();
else
return (elem[top--]);
}

template <class T>
void stack<T>::print() const
{
unsigned int index = top;

while(index != EMPTY)
cout << elem[index--] << endl;
}

template <class T>
bool operator==(const stack<T> &s1, const stack<T> &s2)
{
bool result = true;

if(s1.get_dim() == s2.get_dim() && s1.get_top() == s2.get_top() && s1.get_top() != s1.EMPTY)
for(int i = 0; i <= s1.get_top() && result; ++i)
if(!(s1[i] == s2[i]))
result = false;
else
result = false;
return result;
}


template <class T>
stack<T>& stack<T>::operator=(const stack<T> &s)
{
dim = s.dim;
top = s.top;
elem = new T[dim];
for(int i = 0; i <= top; ++i)
elem[i] = s.elem[i];
return *this;
}


// file stack.cc

#include "stack.h"

/* semplice test */
int main()
{
stack<int> s1(10), s2(10);

for(int i = 0; i < 10; ++i) {
s1.push(i);
s2.push(i);
}

if(s1 == s2)
cout << "s1 = s2\n";

cout << "s1[top] = " << s1.pop() << endl;
}


Grazie anticipatamente per le eventuali risposte! :D

riemann_01
25-06-2006, 10:31
Ho risolto il problema dichiarando la funzione operator==() all'esterno della classe. Questo pero' e' un semplice un workaround, perche' la soluzione adotatta precedentemente non funziona? Nessuno puo' darmi indicazioni a riguardo?

Black imp
25-06-2006, 12:05
prova così: dichiara l'operatore == come una funzione a sua volta template e usa al posto di T per chiarezza un'altro nome

friend
template<class S>
bool operator==(const stack<S> &s1, const stack<S> &s2);


onestamente non so dove vada messa la parola 'friend' se prima o dopo template. fai delle prove. sostanzialmente come l'hai definita tu non è una funzione template e quando le passi i due stack<int> non li accetta.


fammi sapere gentilmente perchè mi interessa :)