I have an operator overloading question...
I have attempted to overload the >> operator so I can
read a file directly into a "SongInfo" object, and attempted to
overload the << operator so I can display a "SongInfo"
object directly to dos console. When attempting to compile, I
recieve, "overloaded operator must take exactly one argument.." errors for both insertion and extraction operators. My code seems to follow closely examples out of my book which clearly shows these
operators taking 2 arguments. What am I doing wrong?

Using DevCpp

Overloaded operators are used in the load_file() and view_tracks() functions.

#include<iostream>
#include<fstream>
#include<iomanip>

using namespace std;

struct SongInfo 
{
   int track_no,
       track_pos,
       track_length,       
       runtime;       
           
   SongInfo *next;     
  
   [b]ifstream& operator>> (ifstream &ins, SongInfo *target);
   ostream& operator<< (ostream &outs, SongInfo *target);[/b]
};

class CDmanager
{
   public:
          
   CDmanager();
   ~CDmanager();
   void load_file();
   void set_runtime(SongInfo*);
   void view_tracks();  
   
   private:
           
   int current_runtime;       
   ifstream infile;       
   SongInfo *head_ptr;
};

int main()
{
    CDmanager CD;
        
    CD.load_file();    
    CD.view_tracks(); 

return 0;
}

/////////////////////////////////
///  Function Definitions //////
///////////////////////////////

[b]SongInfo& SongInfo::operator>> (ifstream &ins, SongInfo *target)
{
   ins >> target->track_no >> target->track_pos >> target->track_len_min
       >> target->track_len_sec;
   return ins;
}

SongInfo& SongInfo::operator<< (ostream &outs, SongInfo *source)
{
   outs << temp->track_no  << setw(10) 
        << temp->track_pos << setw(10)  
        << temp->track_len_min << ':' 
        << temp->track_len_sec << setw(10) 
        << temp->runtime/60 << ':'
        << temp->runtime%60 << setw(10);
   return outs;
}[/b]

CDmanager::CDmanager()
{
   current_runtime = 0;
   infile.clear();
   head_ptr = NULL;
}

CDmanager::~CDmanager()
{
   SongInfo *temp = NULL;  
                       
   while(head_ptr)
   {
      temp = head_ptr->next;  
      delete head_ptr;
      head_ptr = temp;
   }
}

void CDmanager::load_file()
{
   SongInfo *temp = head_ptr;                    
                      
   infile.open("C:\\songs.dat");
   
   if(infile.fail())
   {
      cout << "\n\n\t\aError Opening File!  Program Will Now Terminate.";
      cout << "\n\n\tPress [Enter] to continue... ";
      cin.get();
      exit(1);
   }  
   
   [b]while(infile >> temp)[/b]
   {
      set_runtime(temp);
      temp->next = new SongInfo;
      temp = temp->next;
      temp->next = NULL;
   }
   
   infile.close();   
}

void CDmanager::set_runtime(SongInfo *temp)
{ 
   current_runtime += temp->track_length;
   temp->runtime = current_runtime;
}

void CDmanager::view_tracks()
{   
   SongInfo *temp = head_ptr;
                        
   cout << "\n\nTrack"   << setw(10) << "Song No." << setw(10) 
        << "Song Length" << setw(10) << "Cumulative Runtime";
   cout << "\n-----"     << setw(10) << "--------" << setw(10)
        << "-----------" << setw(10) << "------------------";
                        
   while(temp)
   {
       [b]cout << endl << temp;[/b]
       temp = temp->next;
   }
   
   cout << "\n\n\tTotal Runtime is: " 
        << current_runtime/60 << ':' 
        << current_runtime%60;
}

any help is greatly appreciated.

Recommended Answers

All 6 Replies

Do this

struct SongInfo
{
   int track_no,
       track_pos,
       track_len_min,
       track_len_sec,
       runtime;

   SongInfo *next;

   [B]friend [/B]ifstream& operator>> (ifstream& ins, SongInfo *target);
   [B]friend [/B]ostream& operator<< (ostream& outs, SongInfo *target);
};

[B]ifstream[/B]& SongInfo::operator>> (ifstream& ins, SongInfo *target)
{
   ins >> target->track_no >> target->track_pos >> target->track_len_min
       >> target->track_len_sec;
   return ins;
}

[B]ostream[/B]& SongInfo::operator<< (ostream& outs, SongInfo *[B]source[/B])
{
   outs << [B]source[/B]->track_no  << setw(10) 
        << [B]source[/B]->track_pos << setw(10)  
        << [B]source[/B]->track_len_min << ':' 
        << [B]source[/B]->track_len_sec << setw(10) 
        << [B]source[/B]->runtime/60 << ':'
        << [B]source[/B]->runtime%60 << setw(10);
   return outs;
}

There are a lot of other errors in your code. Pay attention to the compiler errors and you will be able to fix them yourself.

I have made the suggested changes.. yet I get the same errors relating to the number of arguments of my overloaded operators. I have worked on this code.. and have got it down to just operator overloading errors (as far as the compiler is concerned):

#include<iostream>
#include<fstream>
#include<iomanip>

using namespace std;

struct SongInfo 
{
   int track_no,
       track_pos,
       track_length,      
       runtime;       
           
   SongInfo *next;     
  
   friend ifstream& operator>> (ifstream& ins, SongInfo* target);
   friend ostream& operator<< (ostream& outs, SongInfo* target);
};

class CDmanager
{
   public:
          
   CDmanager();
   ~CDmanager();
   void load_file();
   void set_runtime(SongInfo*);
   void view_tracks();  
   
   private:
           
   int current_runtime;       
   ifstream infile;       
   SongInfo *head_ptr;
};

int main()
{
    CDmanager CD;
        
    CD.load_file();    
    CD.view_tracks(); 

return 0;
}

/////////////////////////////////
///  Function Definitions //////
///////////////////////////////

SongInfo& SongInfo::operator>> (ifstream& ins, SongInfo* target)
{
   ins >> target->track_no >> target->track_pos >> target->track_length;       
   return ins;
}

SongInfo& SongInfo::operator<< (ostream& outs, SongInfo* source)
{
   outs << source->track_no  << setw(10) 
        << source->track_pos << setw(10)  
        << source->track_length/60 << ':' 
        << source->track_length%60 << setw(10)         
        << source->runtime/60 << ':'
        << source->runtime%60;
   return outs;
}

CDmanager::CDmanager()
{
   current_runtime = 0;
   infile.clear();
   head_ptr = NULL;
}

CDmanager::~CDmanager()
{
   SongInfo *temp = NULL;  
                       
   while(head_ptr)
   {
      temp = head_ptr->next;  
      delete head_ptr;
      head_ptr = temp;
   }
}

void CDmanager::load_file()
{
   SongInfo *temp = head_ptr;                    
                      
   infile.open("C:\\songs.dat");
   
   if(infile.fail())
   {
      cout << "\n\n\t\aError Opening File!  Program Will Now Terminate.";
      cout << "\n\n\tPress [Enter] to continue... ";
      cin.get();
      exit(1);
   }  
   
   while(infile >> temp)
   {
      set_runtime(temp);
      temp->next = new SongInfo;
      temp = temp->next;
      temp->next = NULL;
   }
   
   infile.close();   
}

void CDmanager::set_runtime(SongInfo* temp)
{ 
   current_runtime += temp->track_length;
   temp->runtime = current_runtime;
}

void CDmanager::view_tracks()
{   
   SongInfo *temp = head_ptr;
                        
   cout << "\n\nTrack"   << setw(10) << "Song No." << setw(10) 
        << "Song Length" << setw(10) << "Cumulative Runtime";
   cout << "\n-----"     << setw(10) << "--------" << setw(10)
        << "-----------" << setw(10) << "------------------";
                        
   while(temp)
   {
       cout << endl << temp;
       temp = temp->next;
   }
   
   cout << "\n\n\tTotal Runtime is: " 
        << current_runtime/60 << ':' 
        << current_runtime%60;
}

Compiler:

Compiler: Default compiler
Executing  g++.exe...
g++.exe "F:\Dev-Cpp\cdmanager.cpp" -o "F:\Dev-Cpp\cdmanager.exe"    -I"F:\Dev-Cpp\lib\gcc\mingw32\3.4.2\include"  -I"F:\Dev-Cpp\include\c++\3.4.2\backward"  -I"F:\Dev-Cpp\include\c++\3.4.2\mingw32"  -I"F:\Dev-Cpp\include\c++\3.4.2"  -I"F:\Dev-Cpp\include"   -L"F:\Dev-Cpp\lib" 
F:\Dev-Cpp\cdmanager.cpp:52: error: `SongInfo& SongInfo::operator>>(std::ifstream&, SongInfo*)' must take exactly one argument

F:\Dev-Cpp\cdmanager.cpp:52: error: no `SongInfo& SongInfo::operator>>(std::ifstream&, SongInfo*)' member function declared in class `SongInfo'

F:\Dev-Cpp\cdmanager.cpp: In member function `SongInfo& SongInfo::operator>>(std::ifstream&, SongInfo*)':
F:\Dev-Cpp\cdmanager.cpp:54: error: invalid initialization of reference of type 'SongInfo&' from expression of type 'std::basic_ifstream<char, std::char_traits<char> >'
F:\Dev-Cpp\cdmanager.cpp: At global scope:
F:\Dev-Cpp\cdmanager.cpp:58: error: `SongInfo& SongInfo::operator<<(std::ostream&, SongInfo*)' must take exactly one argument

F:\Dev-Cpp\cdmanager.cpp:58: error: no `SongInfo& SongInfo::operator<<(std::ostream&, SongInfo*)' member function declared in class `SongInfo'

F:\Dev-Cpp\cdmanager.cpp: In member function `SongInfo& SongInfo::operator<<(std::ostream&, SongInfo*)':
F:\Dev-Cpp\cdmanager.cpp:65: error: invalid initialization of reference of type 'SongInfo&' from expression of type 'std::basic_ostream<char, std::char_traits<char> >'

Execution terminated
struct SongInfo
{
   int track_no,
       track_pos,
       track_len_min,
       track_len_sec,
       runtime;

   SongInfo *next;

   friend ifstream& operator>> (ifstream& ins, SongInfo *target);
   friend ostream& operator<< (ostream& outs, SongInfo *target);
};

ifstream& [B]SongInfo::[/B]operator>> (ifstream& ins, SongInfo *target)
{
   ins >> target->track_no >> target->track_pos >> target->track_len_min
       >> target->track_len_sec;
   return ins;
}

ostream& [B]SongInfo::[/B]operator<< (ostream& outs, SongInfo *source)
{
   outs << source->track_no  << setw(10) 
        << source->track_pos << setw(10)  
        << source->track_len_min << ':' 
        << source->track_len_sec << setw(10) 
        << source->runtime/60 << ':'
        << source->runtime%60 << setw(10);
   return outs;
}

oops. I forgot to tell you to delete the parts above in red. The final code should be like below.

struct SongInfo
{
   int track_no,
       track_pos,
       track_len_min,
       track_len_sec,
       runtime;

   SongInfo *next;

   friend ifstream& operator>> (ifstream& ins, SongInfo *target);
   friend ostream& operator<< (ostream& outs, SongInfo *target);
};

ifstream& operator>> (ifstream& ins, SongInfo *target)
{
   ins >> target->track_no >> target->track_pos >> target->track_len_min
       >> target->track_len_sec;
   return ins;
}

ostream& operator<< (ostream& outs, SongInfo *source)
{
   outs << source->track_no  << setw(10) 
        << source->track_pos << setw(10)  
        << source->track_len_min << ':' 
        << source->track_len_sec << setw(10) 
        << source->runtime/60 << ':'
        << source->runtime%60 << setw(10);
   return outs;
}
commented: Helps-[G] +2

This operator overloading business is just kicking my rear end..

#include<iostream>
#include<fstream>
#include<iomanip>

using namespace std;

struct SongInfo 
{
   int track_no,
       track_pos,
       track_length,      
       runtime;       
           
   SongInfo *next;     
  
   friend ifstream& operator>> (ifstream& ins, SongInfo* target);
   friend ostream& operator<< (ostream& outs, SongInfo* target);
};

class CDmanager
{
   public:
          
   CDmanager();
   ~CDmanager();
   void load_file();
   void set_runtime(SongInfo*);
   void view_tracks();  
   
   private:
           
   int current_runtime;       
   ifstream infile;       
   SongInfo *head_ptr;
};

int main()
{
    CDmanager CD;
        
    CD.load_file();    
    CD.view_tracks(); 

return 0;
}

/////////////////////////////////
///  Function Definitions //////
///////////////////////////////

SongInfo& operator>> (ifstream& ins, SongInfo* target)
{
   ins >> target->track_no >> target->track_pos >> target->track_length;       
   return ins;
}

SongInfo& operator<< (ostream& outs, SongInfo* source)
{
   outs << source->track_no  << setw(10) 
        << source->track_pos << setw(10)  
        << source->track_length/60 << ':' 
        << source->track_length%60 << setw(10)         
        << source->runtime/60 << ':'
        << source->runtime%60 << setw(10);
   return outs;
}

CDmanager::CDmanager()
{
   current_runtime = 0;
   infile.clear();
   head_ptr = NULL;
}

CDmanager::~CDmanager()
{
   SongInfo *temp = NULL;  
                       
   while(head_ptr)
   {
      temp = head_ptr->next;  
      delete head_ptr;
      head_ptr = temp;
   }
}

void CDmanager::load_file()
{
   SongInfo *temp = head_ptr;                    
                      
   infile.open("C:\\songs.dat");
   
   if(infile.fail())
   {
      cout << "\n\n\t\aError Opening File!  Program Will Now Terminate.";
      cout << "\n\n\tPress [Enter] to continue... ";
      cin.get();
      exit(1);
   }  
   
   while(temp)
   {
      infile >> temp;
      set_runtime(temp);
      temp->next = new SongInfo;
      temp = temp->next;
      temp->next = NULL;
   }
   
   infile.close();   
}

void CDmanager::set_runtime(SongInfo* temp)
{ 
   current_runtime += temp->track_length;
   temp->runtime = current_runtime;
}

void CDmanager::view_tracks()
{   
   SongInfo *temp = head_ptr;
                        
   cout << "\n\nTrack"   << setw(10) << "Song No." << setw(10) 
        << "Song Length" << setw(10) << "Cumulative Runtime";
   cout << "\n-----"     << setw(10) << "--------" << setw(10)
        << "-----------" << setw(10) << "------------------";
                        
   while(temp)
   {
       cout << endl << temp;
       temp = temp->next;
   }
   
   cout << "\n\n\tTotal Runtime is: " 
        << current_runtime/60 << ':' 
        << current_runtime%60;
}

Compiler:

Compiler: Default compiler
Executing  g++.exe...
g++.exe "F:\Dev-Cpp\cdmanager.cpp" -o "F:\Dev-Cpp\cdmanager.exe"    -I"F:\Dev-Cpp\lib\gcc\mingw32\3.4.2\include"  -I"F:\Dev-Cpp\include\c++\3.4.2\backward"  -I"F:\Dev-Cpp\include\c++\3.4.2\mingw32"  -I"F:\Dev-Cpp\include\c++\3.4.2"  -I"F:\Dev-Cpp\include"   -L"F:\Dev-Cpp\lib" 
F:\Dev-Cpp\cdmanager.cpp: In function `SongInfo& operator>>(std::ifstream&, SongInfo*)':
F:\Dev-Cpp\cdmanager.cpp:52: error: new declaration `SongInfo& operator>>(std::ifstream&, SongInfo*)'
F:\Dev-Cpp\cdmanager.cpp:16: error: ambiguates old declaration `std::ifstream& operator>>(std::ifstream&, SongInfo*)'

F:\Dev-Cpp\cdmanager.cpp: In function `SongInfo& operator>>(std::ifstream&, SongInfo*)':
F:\Dev-Cpp\cdmanager.cpp:54: error: invalid initialization of reference of type 'SongInfo&' from expression of type 'std::basic_ifstream<char, std::char_traits<char> >'
F:\Dev-Cpp\cdmanager.cpp: In function `SongInfo& operator<<(std::ostream&, SongInfo*)':
F:\Dev-Cpp\cdmanager.cpp:58: error: new declaration `SongInfo& operator<<(std::ostream&, SongInfo*)'
F:\Dev-Cpp\cdmanager.cpp:17: error: ambiguates old declaration `std::ostream& operator<<(std::ostream&, SongInfo*)'

F:\Dev-Cpp\cdmanager.cpp: In function `SongInfo& operator<<(std::ostream&, SongInfo*)':
F:\Dev-Cpp\cdmanager.cpp:65: error: invalid initialization of reference of type 'SongInfo&' from expression of type 'std::basic_ostream<char, std::char_traits<char> >'

Execution terminated

Look closely at the return types of the overloaded >> and <<.

/////////////////////////////////
///  Function Definitions //////
///////////////////////////////

[B]SongInfo[/B]& operator>> (ifstream& ins, SongInfo* target)
{
   ins >> target->track_no >> target->track_pos >> target->track_length;       
   return ins;
}

[B]SongInfo[/B]& operator<< (ostream& outs, SongInfo* source)
{
   outs << source->track_no  << setw(10) 
        << source->track_pos << setw(10)  
        << source->track_length/60 << ':' 
        << source->track_length%60 << setw(10)         
        << source->runtime/60 << ':'
        << source->runtime%60 << setw(10);
   return outs;
}

Since you are returning objects of ifstream and ostream, the code should be like this.

/////////////////////////////////
///  Function Definitions //////
///////////////////////////////

[B]ifstream[/B]& operator>> (ifstream& ins, SongInfo* target)
{
   ins >> target->track_no >> target->track_pos >> target->track_length;       
   return ins;
}

[B]ostream[/B]& operator<< (ostream& outs, SongInfo* source)
{
   outs << source->track_no  << setw(10) 
        << source->track_pos << setw(10)  
        << source->track_length/60 << ':' 
        << source->track_length%60 << setw(10)         
        << source->runtime/60 << ':'
        << source->runtime%60 << setw(10);
   return outs;
}

I have a lot of debugging work ahead of me.. but at least I can get this thing to compile. Thank you for your help with this problem.. operator overloading has always been a mystery to me.. but thanks to your help I think I am starting to get the hang of it.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.