Thread: A simple question about "friend" in template classes

  1. #1
    Registered User
    Join Date
    Apr 2007
    Posts
    284

    A simple question about "friend" in template classes

    I implemented a class for auto pointer.
    It seems that I can NOT override an operator<< in this class?
    The complier reports:
    Code:
    main.cc:18: warning: friend declaration `std::ostream& 
       operator<<(std::ostream&, const AutoPtr<T>&)' declares a non-template 
       function
    main.cc: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
    Here is the code:

    Code:
    template <typename T>                                                                                                                                                        
    class AutoPtr{                                                                                                                                                               
    private:                                                                                                                                                                     
        T* ptr;                                                                                                                                                                  
    public:                                                                                                                                                                      
        AutoPtr(T* p=0);                                                                                                                                                         
        ~AutoPtr();                                                                                                                                                              
        AutoPtr(AutoPtr<T>& rhs);                                                                                                                                                
        AutoPtr<T>& operator = (AutoPtr<T>& rhs);                                                                                                                                
        T operator*() const;                                                                                                                                                     
        T* operator->() const;                                                                                                                                                   
        friend ostream& operator<<(ostream& os, const AutoPtr<T>& obj);      //Error here.                                                                                              
    };                                                                                                                                                                           
                                                                                                                                                                                 
    template <typename T>                                                                                                                                                        
    ostream&                                                                                                                                                                     
    operator<<(ostream& os, const AutoPtr<T>& obj){                                                                                                                              
        if (obj.ptr)                                                                                                                                                             
            os<<*(obj.ptr)<<endl;                                                                                                                                                
        else                                                                                                                                                                     
            os<<"<NULL>"<<endl;                                                                                                                                                  
        return os;                                                                                                                                                               
    }                                                                                                                                                                            
                                                                                                                                                                                 
    template <typename T>                                                                                                                                                        
    AutoPtr<T>::AutoPtr(T* p):ptr(p){}                                                                                                                                           
                                                                                                                                                                                 
    template <typename T>                                                                                                                                                        
    AutoPtr<T>::~AutoPtr(){                                                                                                                                                      
        delete(ptr);                                                                                                                                                             
    }                                                                                                                                                                            
                                                                                                                                                                                 
    template <typename T>                                                                                                                                                        
    AutoPtr<T>::AutoPtr(AutoPtr<T>& rhs){                                                                                                                                        
        ptr = rhs.ptr;                                                                                                                                                           
        rhs.ptr=0;                                                                                                                                                               
    } 
    
    template <typename T>                                                                                                                                                        
    AutoPtr<T>&                                                                                                                                                                  
    AutoPtr<T>::operator=(AutoPtr<T>& rhs){                                                                                                                                      
        if(this != &rhs){                                                                                                                                                        
            this->ptr = rhs.ptr;                                                                                                                                                 
            rhs.ptr=0;                                                                                                                                                           
        }                                                                                                                                                                        
        return (*this);                                                                                                                                                          
    }                                                                                                                                                                            
                                                                                                                                                                                 
    template <typename T>                                                                                                                                                        
    T                                                                                                                                                                            
    AutoPtr<T>::operator*()const{                                                                                                                                                
        return *ptr;                                                                                                                                                             
    }                                                                                                                                                                            
                                                                                                                                                                                 
    template <typename T>                                                                                                                                                        
    T*                                                                                                                                                                           
    AutoPtr<T>::operator->()const{                                                                                                                                               
        return ptr;                                                                                                                                                              
    }                                                                                                                                                                            
                                                                                                                                                                                 
    int main(){                                                                                                                                                                  
        AutoPtr<int> ptr;                                                                                                                                                        
        cout<<ptr;                                                                                                                                                               
        AutoPtr<int> ptr2(new int(100));                                                                                                                                         
        cout<<ptr2;                                                                                                                                                              
        /*                                                                                                                                                                       
        ptr(ptr2);                                                                                                                                                               
        cout<<ptr;                                                                                                                                                               
        cout<<ptr2;                                                                                                                                                              
        AutoPtr<int> ptr3;                                                                                                                                                       
        ptr3 = ptr;                                                                                                                                                              
        cout<<ptr;                                                                                                                                                               
        cout<<ptr3;                                                                                                                                                              
        */                                                                                                                                                                       
        return 0;                                                                                                                                                                
    }

  2. #2
    Registered User
    Join Date
    Jun 2007
    Posts
    41
    Code:
    template <typename T> friend ostream& operator<<(ostream& os, const AutoPtr<T>&obj);
    ?

  3. #3
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    That friends every instantiation to every instantiation. To just friend an instantiation for T to the instantiation for T, follow the compiler's advice:
    Code:
    template <typename T>
    class AutoPtr;
    
    template <typename T>                                                                                                                                                        
    ostream&                                                                                                                                                                     
    operator<<(ostream& os, const AutoPtr<T>& obj);
    
    template <typename T>
    class AutoPtr
    {
      // ...
      friend ostream& operator<< <>(ostream& os, const AutoPtr<T>& obj);
    };
    
    template <typename T>                                                                                                                                                        
    ostream&                                                                                                                                                                     
    operator<<(ostream& os, const AutoPtr<T>& obj){                                                                                                                              
        if (obj.ptr)                                                                                                                                                             
            os<<*(obj.ptr)<<endl;                                                                                                                                                
        else                                                                                                                                                                     
            os<<"<NULL>"<<endl;                                                                                                                                                  
        return os;                                                                                                                                                               
    }
    Ought to work, but I haven't tried it.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Implicit template argument deduction for classes
    By drrngrvy in forum C++ Programming
    Replies: 12
    Last Post: 03-30-2007, 05:31 PM
  2. Quick question about class template
    By merixa in forum C++ Programming
    Replies: 5
    Last Post: 12-06-2005, 11:43 PM
  3. simple template question
    By Cobras2 in forum C++ Programming
    Replies: 5
    Last Post: 09-14-2005, 03:16 AM
  4. question about .net to 6.0 change causing errors
    By jverkoey in forum C++ Programming
    Replies: 17
    Last Post: 03-23-2004, 10:45 AM
  5. Simple yes/no question regarding classes
    By Ricochet in forum C++ Programming
    Replies: 5
    Last Post: 12-11-2003, 05:06 PM