Link to home
Start Free TrialLog in
Avatar of theakst
theakst

asked on

overloaded operators with friend functions

Hi Experts,

Am trying to declare a template pointer to an object that will be passed to an overloaded friend fn.

eg:

class dec'l:

template <class ElemType>
class Set {

 private:
     listNode<ElemType> *head;

 public:
     Set ();
     ~Set ();
     Set (const Set &);
     Set & operator= (const Set &rhs);
        // some other stuff ...
    friend ostream & operator<< <ElemType>(ostream & os, const Set & s);
};

declare pointer:
 
        Set< int > *printSet;           // Set< int > here causes compiler to barf..
           if (driver_sets[k3]._set->size() > 0)
          {
          printSet = driver_sets[k3]._set;      
          cout << "Set " << driver_sets[k3]._name << "={" << (*printSet);      
          }
        else cout << "Set " << result << "={}" << endl;
        }

overloaded friend fn declaration:

ostream &operator<< <ElemType>(ostream & os, const Set & s)
{
     listNode *locator;
     if ( s.head != NULL )
        locator = s.head;
 
     os << locator->getData();
     while ( locator->getNext() != NULL )
        {
           locator = locator->getNext();
        os << "," << locator->getData();
        }
     os << "}" << endl;    
     return os;
}

 I know I'm missing something, but what is it?

Thxs!!
SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hi theakst,
You can't create a friend template friend function.

David Maisonave :-)
Cheers!
Avatar of theakst
theakst

ASKER


jk:

template<typename ElemType>
ostream &operator<< <ElemType>(ostream & os, const Set & s)

will still put out large error large error msg with pointer decl:      
Set< int > *printSet;  

David,

how would I go about solving the problem,  ( how do I avoid friend templating a friend functiion?)

Txs
>>how would I go about solving the problem,  ( how do I avoid friend templating a friend functiion?)

A common method is to create member functions that are called by the global function.

Put all your logic in the member functions, and have your global function call the member functions.
Avatar of theakst

ASKER

eg:

class dec'l:

template <class ElemType>
class Set {

 private:
     listNode<ElemType> *head;
     void printFn( Set *printPtr );       //<--new member print fn

 public:
        // constructors ...
        // some other stuff ...
    friend ostream & operator<< <ElemType>(ostream & os, const Set & s);
};

Set.cc:

void Set::printFn( Set *printPtr );
         {
         char* name = new char[50];
         cin >> name;
         Set *printSet;
         bool _print = false;
         while ( _print == false )
         {
         for ( int k = 0; k < MAX_NUM_OF_STRUCTS; k++ )
                  if (strcmp (driver_sets[k]._name, name) == 0)
               {
             if (driver_sets[k]._set->size() > 0)
                {
                printSet = driver_sets[k]._set;      
                cout << "Set " << driver_sets[k]._name << "={" << (*printSet);       
                _print = true;
                }
             else
                _print = true;    
              }  
         for ( int k = 0; k < MAX_NUM_OF_STRUCTS; k++ )
            if (driver_sets[k]._name == "" && _print == false)
               {
             //cout << "record not found" << endl;
               driver_sets[k]._name = name;
             cout << "Set " << name << "={}" << endl;
             _print = true;            
             }         
          }}

Global fn:

printFn(  printSet ) //<--pass data to be printed here

templates are only provided in the member fn...

would this be the correct (not necessarily neatest) syntax?
Avatar of theakst

ASKER

what about puting the << overloaded operato into the header:

class dec'l:

template <class ElemType>
class Set {

 private:
     listNode<ElemType> *head;
     friend ostream & operator<< <ElemType>(ostream & os, const Set & s);

 public:
        // constructors ...
        // some other stuff ...
    friend ostream & operator<< <ElemType>(ostream & os, const Set & s);
};
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
As you can see, in my example, I removed the <ElemType> that was in the friend declaration.
Avatar of theakst

ASKER

Kool,

Thanks for all on a friday afternoon!!

It's seems I was wrong about creating a friend template global function.

The above code can also be done with the following syntax:

template <class ElemType>
class Set {
      
      public:
            Set(const ElemType &x):m_x(x){}
            friend ostream & operator<< (ostream & os, const Set & s);
      private:
            ElemType m_x;
};

template<typename ElemType>
ostream &operator<< (ostream & os, const Set<ElemType> & s)
{
      os << s.m_x;
      return os;
}

void main()
{
      Set <int>s(1);
      
      cout << s << endl;
FYI:

I know there is an issue with making a friend in a template class, but I don't remember the details.