Link to home
Start Free TrialLog in
Avatar of deekakes
deekakes

asked on

How to call a friend function from within another function's parameter list.

Hello all:

I am having a problem with a compare_last_name function that I have defined as a friend of a Book class. I am trying to call this function from within a sort function in the main program. I can't seem to get the parameters correct for compare_last_name function within the sort function's parameter list.

thank you for any help

 ---------------------------------------

//file name: book8.h

#include <string>
using namespace std;

# ifndef BOOK_H
# define BOOK_H

class Book
{
      public:
            Book() { };
            Book(string an_author_first_name, string an_author_last_name,
                   string a_title,string a_publisher, string an_isbn,
                   string a_pub_year, string a_page_count, string a_price,
                   string book_type);
//            ~Book();
            
            string get_author_first_name() const;
                         .
                                             .
                                             .
                                             .                
                                   .
                                             .
                                             .
                                             .
            friend istream& operator>>(istream&, Book&);
            friend ostream& operator<<(ostream&, Book&);
            friend bool compare_last_name(const Book&, const Book&);
            
            void print_books();

      private:
            string author_first_name;
            string author_last_name;
            string title;
            string publisher;
            string isbn;
            string pub_year;
            string page_count;
            string price;
            string book_type;
};
#endif;

// file name: book8.cpp
// implementation file for Book class

#include <iostream>
#include <sstream>
#include <iomanip>
#include "book8.h"

using namespace std;

string Book::get_author_first_name() const
{
      return author_first_name;
}
                         .
                         .
                         .
                         .

istream& operator>>(istream& infile, Book& a_book)
{
 
      istringstream strin;
      string line;

      getline(infile, line);
      strin.str(line);
      strin  >> a_book.author_first_name >> a_book.author_last_name
               >> a_book.title >> a_book.publisher >> a_book.isbn
               >> a_book.pub_year >> a_book.page_count
               >> a_book.price >> a_book.book_type ;
 
      return infile;
}

                             
ostream& operator<<(ostream& outfile, Book& a_book)
{
 
      cout    << a_book.author_first_name << " " << a_book.author_last_name
                << " " << a_book.title << " " << a_book.publisher << " " 
                  << a_book.isbn << " " <<  a_book.pub_year << " "
                  << a_book.page_count << " " << a_book.price << " "
                  << a_book.book_type << endl  ;      
      
      outfile << a_book.author_first_name << " " << a_book.author_last_name
                << " " << a_book.title << " " << a_book.publisher << " " 
                  << a_book.isbn << " " <<  a_book.pub_year << " "
                  << a_book.page_count << " " << a_book.price << " "
                  << a_book.book_type << endl  ;      
      
      return outfile;
}

bool compare_last_name(const Book& b_book, const Book& a_book)
{
      return b_book.author_last_name < a_book.author_last_name ||
               (b_book.author_last_name == a_book.author_last_name &&
               b_book.author_first_name < a_book.author_first_name) ||
               (b_book.author_last_name == a_book.author_last_name &&
               b_book.author_first_name == a_book.author_first_name &&
               b_book.title < a_book.title);
}

//file name: book_user8.cpp

#include <list>
#include <string>
#include <fstream>
#include <iostream>
#include <algorithm>
#include "book8.h"

using namespace std;

void fill_list(list<Book>&, istream&);

template <class T>
inline void print_list(T& L, ostream& outfile, char* optional="")
{
      typename T::iterator pos;

      outfile << optional << endl;
      cout << optional << endl << endl;
      
      for (pos = L.begin(); pos != L.end(); ++pos)
      {
            outfile << *pos << ' ';
      }
      outfile << endl;
}

int main()
{
      list<Book> book_list;
      ifstream fin;
      ofstream fout;

      fin.open("C:\\CSC311\\Files\\book8_in.txt");
            
      if(fin.fail())
      {
            cout << "Failed to open input file" << endl;
            exit(1);
      }

      fout.open("C:\\CSC311\\Files\\book8_out.txt");

      if(fout.fail())
      {
            cout << "Failed to open output file"  << endl;
            exit(1);
      }

      fill_list(book_list, fin);
      print_list(book_list, fout, "Book List:\n");

    sort(book_list.begin(), book_list.end(), compare_last_name(b_book, a_book));
      print_list(book_list, fout, "Sorted Book List by Last Name:\n");
      
      fin.close();
      fout.close();      
      return 0;
}

void fill_list(list<Book>& book_list, istream& infile)
{
      Book a_book;

      while (!infile.eof())
      {
            infile >> a_book;
            book_list.push_back(a_book);
      }
}


SOLUTION
Avatar of Exceter
Exceter
Flag of United States of America 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
Avatar of bcladd
bcladd

(1) STL list<> does not have random access iterators so you CANNOT use the stand alone sort algorithm. Instead you have to call list's sort:

  book_list.sort(compare_last_name);

Notice no parameter list; you're passing a pointer at the comparison function to sort.

Hope this helps, -bcl
Avatar of deekakes

ASKER

I added book_list.sort(compare_last_name) to the main program and the compiler states:

C:\CSC311\Files\book_user8.cpp(55) : error C2664: 'void __thiscall std::list<class Book,class std::allocator<class Book> >::sort(struct std::greater<class Book>)' : cannot convert parameter 1 from 'bool (const class Book &,const class Book &)' to 's
truct std::greater<class Book>'
        No constructor could take the source type, or constructor overload resolution was ambiguous
Error executing cl.exe.

book_user8.obj - 1 error(s), 0 warning(s)
What compiler are you using? I tested the line in Borland 5.5 (didn't have any data so I didn't run the resulting program). According to Josuttis' _The C++ Standard Library_ there are two versions of sort for list, one with no parameters and one with a single parameter, CompFunction op. It warns that the second form of sort is available only in systems that support member templates.

That is what I know.

-bcl
I'm using VC++ 6.0.
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
Note: operator() must be public (put public: before the function declaration) and you may need to #include <functional> to make it work.

-bcl
Thanks!