View Single Post
Newbie Member
12Jul2008,19:08  
jogojapan's Avatar
This reply may be somewhat late, but as I was facing a similar problem just now and found this discussion, let me add one important remark that anybody reading the above will find helpful.

rockoder was right about the "<>" after the name of the function being necessary. The fact that shabbir is able to compile his code without adding it may indicate that he is using a compiler that is not very strict. But for example when using gcc 4.1, the "<>" is absolutely necessary to avoid the warnings and with ldd 2.7 it is necessary to avoid the linker errors.

Now the reason why jijojs was still facing errors after making the correction is that a function (regardless of whether it is a template function or ordinary function) can never be declared "friend" of a class if its prototype wasn't declared before.

So before the class definition of "Derived", you need the function prototype for the "operator<<" template. Moreover, because the operator<< takes an argument of type "Derived<T>", you must insert a forward-declaration of the class template, too.

In the code this will look as follows:

Code:
template <typename T> class Derived;

template <typename T>
ostream& operator<<(ostream&,const Derived<T>&);

template <typename T>
istream& operator>>(istream&,Derived<T>&);

template <typename T>
class Derived : public Base<T>
{
    public:
        //Default Functions also provided
        Derived(const T q = NULL): Base<T>(q){}
        Derived(const Derived &d): Base<T>(d.strQuery){}
        ~Derived(){}
        Derived<T> operator=(const Derived<T> d)
        {
            if(this != &d)
                this->strQuery=d.strQuery;
            return *this;
        }
        
        //Input Output Functions 
        friend ostream& operator<< <>(ostream&,const Derived<T>&);
        friend istream& operator>> <>(istream&,Derived<T>&);

        //op + Functionality
        Derived<T> operator + (const Derived<T>) const;
        Derived<T> operator + (const T) const;
        friend Derived<T> operator + (const T,const Derived<T>);
        Derived<T>& operator ++ ();
        Derived<T>& operator ++ (int);
        Derived<T>& operator += (const Derived<T>);
};
You may also want to have a look at
http://cboard.cprogramming.com/showthread.php?t=86607

for a discussion of a similar situation and some alternative ideas.


Another interesting problem arises when the class is defined in a special namespace, i.e. enclosed in something like this:

Code:
namespace special {
 ...
}
It is then important that the operator<< is also declared inside the same namespace. Theoretically it should be possible to make a non-namespace-specific global function a friend of a namespace-specific class, but at least gcc 4.1 does not allow you to do that.
jpope19, spikehazard likes this