By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,507 Members | 1,185 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,507 IT Pros & Developers. It's quick & easy.

friend declaration declares a non-template function

P: n/a
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<charcStack(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::ostream&
operator<<(std::ostream&, 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<charconst&)'
/tmp/ccrvlcDf.o(.text+0x1b8): In function `main':
: undefined reference to `operator<<(std::basic_ostream<char,
std::char_traits<char&, Stack<charconst&)'
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.

Jan 26 '07 #1
Share this Question
Share on Google+
2 Replies


P: n/a
fd*******@gmail.com 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::ostream&
operator<<(std::ostream&, 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<charconst&)'
/tmp/ccrvlcDf.o(.text+0x1b8): In function `main':
: undefined reference to `operator<<(std::basic_ostream<char,
std::char_traits<char&, Stack<charconst&)'
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::ostream& operator<<(std::ostream&, const Stack<T>&)' declares a
non-template function". To make your template operator a friend, you have
to "add <after the function name here".

Jan 26 '07 #2

P: n/a
fd*******@gmail.com 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::ostream&
operator<<(std::ostream&, 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<charconst&)'
/tmp/ccrvlcDf.o(.text+0x1b8): In function `main':
: undefined reference to `operator<<(std::basic_ostream<char,
std::char_traits<char&, Stack<charconst&)'
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::ostream& operator<<(std::ostream&, 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.

Jan 26 '07 #3

This discussion thread is closed

Replies have been disabled for this discussion.