I am trying to overload the output stream operator (<<) for a templated stack class I created (as a programming assignment). I am using the normal paradigm of declaring an friend operator<< function to the stack class. I followed Prata's example (C++ primer plus) of "bound template friend functions to a template class". The code compiles and executes, but doesn't give the desired result because the templated operator<< function is attempting to overload every occurrence of the output stream operator in main, when I only want it to overload the output stream operators for the Stack class. So I think that I need to specialize the overloaded operator<< function.
I constructed a simpler code example to demonstrate the problem. Please note that rather than using an overloaded operator<< in the example, I use a function called "oper()". The code follows (attached too), The problem is that oper() works for both the Bigger class (which I want) AND the BIG class (which I dont want). Can you show me how to specialize the templated oper() function?
// Compiler: gcc
// Purpose: test templates. test bound template friend fns.
#include <iostream>
using namespace std;
// declare template function
template <typename T> std::ostream & oper (std::ostream &os, const T &);
template <typename T> class Bigger {
T value;
public:
Bigger(T init) {value = init;}
// declare bound template friend functions
friend std::ostream &oper<> (std::ostream &os, const Bigger<T> &);
};
class Bad { // but oper() can work with this class too!
int i;
public:
int value;
Bad(): i(1),value(2) {};
};
// define full template functions
// want to specialize this function so that it only works with class Bigger!
template <typename T> std::ostream &oper (std::ostream &os, const T & big) {
os << big.value;
return os;
}
int main (int argc, char * argv[]) {
Bigger <float> bf {3.1};
// this is desired behavior. oper() acts as a friend to Bigger.
cout << "oper bf: "; oper(cout,bf); cout<<endl;
Bad bad;
// this is undesired behavior. template is too loose allowing oper to work for Bad!!!
cout << "oper bad: ";oper(cout,bad);cout<<endl;
return 0;
}