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>:ush(const T& e){
assert(!full());
if (!full())
elements[++top] = e;
else
msg("Stack full!");
}
template<class T>
T Stack<T>:op(){
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:stream&
operator<<(std: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.
#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>:ush(const T& e){
assert(!full());
if (!full())
elements[++top] = e;
else
msg("Stack full!");
}
template<class T>
T Stack<T>:op(){
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:stream&
operator<<(std: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.