friend declaration declares a non-template function

F

fdmfdmfdm

I have the following code:

#include <iostream>
#include <cstdlib>
#include <cassert>
using namespace std;
template <class T>
class Stack{
public:
enum{DefaultStack = 10, EmptyStack = -1};
Stack();
Stack(int);
~Stack();
void push(const T&);
T pop();
T topNoPop() const;
bool empty() const;
bool full() const;
friend ostream& operator<<(ostream& os, const Stack<T>& s);
private:
T* elements;
int top;
int size;
void allocate(){
elements = new T[size];
top = EmptyStack;
}
void msg(char m[]) const{
cout << "*** " << m << " ***" << endl;
}


};

template<class T>
ostream& operator<<(ostream& os, const Stack<T>& s)

{
s.msg("Stack contents:");
int t = s.top;
while (t > s.EmptyStack)
cout << s.elements[t--] << endl;
return os;
}

template<class T>
Stack<T>::Stack(){
size = DefaultStack;
allocate();
}

template<class T>
Stack<T>::Stack(int s){
if (s < 0)
s *= -1;
else if (s == 0)
s = DefaultStack;
size = s;
allocate();
}

template<class T>
Stack<T>::~Stack(){
delete[] elements;
}

template<class T>
void Stack<T>::push(const T& e){
assert(!full());
if (!full())
elements[++top] = e;
else
msg("Stack full!");
}

template<class T>
T Stack<T>::pop(){
assert(!empty());
if (!empty())
return elements[top--];
else{
msg("Stack empty!");
T dummy_value;
return dummy_value; //return arbitrary value
}
}

template<class T>
T Stack<T>::topNoPop() const{
assert(top > EmptyStack);
if (!empty())
return elements[top];
else{
msg("Stack Empty!");
T dummy_value;
return dummy_value;
}
}

template<class T>
bool Stack<T>::empty() const{
return top <= EmptyStack;
}

template<class T>
bool Stack<T>::full() const{
return top + 1 >= size;
}


int main(){

Stack<char> cStack(20);

cout << cStack << endl; //empty stack


cout << "pushing A, B" << endl;
cStack.push('A');
cStack.push('B');
cout << cStack << endl; //BA
return 0;
}


When I compile with g++, there is error like:

stack.cpp:18: warning: friend declaration `std::eek:stream&
operator<<(std::eek:stream&, const Stack<T>&)' declares a non-template
function
stack.cpp:18: 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/ccrvlcDf.o(.text+0x13f): In function `main':
: undefined reference to `operator<<(std::basic_ostream<char,
std::char_traits<char> >&, Stack<char> const&)'
/tmp/ccrvlcDf.o(.text+0x1b8): In function `main':
: undefined reference to `operator<<(std::basic_ostream<char,
std::char_traits<char> >&, Stack<char> const&)'
collect2: ld returned 1 exit status


I think it's totally legal to make a friend function inside a template
class declaration, why there is an error like this?

Thank you.
 
R

Rolf Magnus

(e-mail address removed) wrote:

(snipped the parts that are not relevant)
template <class T>
class Stack{
friend ostream& operator<<(ostream& os, const Stack<T>& s);
};

template<class T>
ostream& operator<<(ostream& os, const Stack<T>& s)

{
s.msg("Stack contents:");
int t = s.top;
while (t > s.EmptyStack)
cout << s.elements[t--] << endl;
return os;
}
When I compile with g++, there is error like:

stack.cpp:18: warning: friend declaration `std::eek:stream&
operator<<(std::eek:stream&, const Stack<T>&)' declares a non-template
function
stack.cpp:18: 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/ccrvlcDf.o(.text+0x13f): In function `main':
: undefined reference to `operator<<(std::basic_ostream<char,
std::char_traits<char> >&, Stack<char> const&)'
/tmp/ccrvlcDf.o(.text+0x1b8): In function `main':
: undefined reference to `operator<<(std::basic_ostream<char,
std::char_traits<char> >&, Stack<char> const&)'
collect2: ld returned 1 exit status


I think it's totally legal to make a friend function inside a template
class declaration, why there is an error like this?

Exactly for the reason that the compiler told you. Your "friend declaration
`std::eek:stream& operator<<(std::eek:stream&, const Stack<T>&)' declares a
non-template function". To make your template operator a friend, you have
to "add <> after the function name here".
 
R

Rolf Magnus

(e-mail address removed) wrote:

(snipped the parts that are not relevant)
template <class T>
class Stack{
friend ostream& operator<<(ostream& os, const Stack<T>& s);
};

template<class T>
ostream& operator<<(ostream& os, const Stack<T>& s)

{
s.msg("Stack contents:");
int t = s.top;
while (t > s.EmptyStack)
cout << s.elements[t--] << endl;
return os;
}
When I compile with g++, there is error like:

stack.cpp:18: warning: friend declaration `std::eek:stream&
operator<<(std::eek:stream&, const Stack<T>&)' declares a non-template
function
stack.cpp:18: 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/ccrvlcDf.o(.text+0x13f): In function `main':
: undefined reference to `operator<<(std::basic_ostream<char,
std::char_traits<char> >&, Stack<char> const&)'
/tmp/ccrvlcDf.o(.text+0x1b8): In function `main':
: undefined reference to `operator<<(std::basic_ostream<char,
std::char_traits<char> >&, Stack<char> const&)'
collect2: ld returned 1 exit status


I think it's totally legal to make a friend function inside a template
class declaration, why there is an error like this?

Exactly for the reason that the compiler told you. Your "friend declaration
`std::eek:stream& operator<<(std::eek:stream&, const Stack<T>&)' declares a
non-template function". To make your template operator a friend, you have
to "make sure the function template has already been declared and add <>
after the function name here".
I know that compilers often produce hard to understand messages, but this
one couldn't be any clearer.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,902
Latest member
Elena68X5

Latest Threads

Top