?
Solved

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

Posted on 2003-11-10
8
Medium Priority
?
536 Views
Last Modified: 2008-03-06
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);
      }
}


0
Comment
Question by:deekakes
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
8 Comments
 
LVL 8

Assisted Solution

by:Exceter
Exceter earned 160 total points
ID: 9714900
Check this out for examples of using std::sort with a custom predicate function,
http://www.codeproject.com/vcpp/stl/stdsort.asp

Cheers!
Exceter
0
 
LVL 11

Expert Comment

by:bcladd
ID: 9714927
(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
0
 

Author Comment

by:deekakes
ID: 9715080
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)
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 11

Expert Comment

by:bcladd
ID: 9715245
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
0
 

Author Comment

by:deekakes
ID: 9715465
I'm using VC++ 6.0.
0
 
LVL 11

Accepted Solution

by:
bcladd earned 240 total points
ID: 9715522
VC++ 6.0 does not supprot member templates so the notation I gave you will not work (guess you figured that part out on your own).

To sort a list you need to specialize std::greater for your class.  This question was also answered here before: http://www.experts-exchange.com/Programming/Programming_Languages/Cplusplus/Q_11073825.html

template<> class std::greater<class Book &>
{
   bool operator()(const Book & pFirst,
                          const Book & pSecond) const
   {
      return compare_last_name(pFirst, pSecond);
   }
};

Hope this helps, -bcl
0
 
LVL 11

Expert Comment

by:bcladd
ID: 9715558
Note: operator() must be public (put public: before the function declaration) and you may need to #include <functional> to make it work.

-bcl
0
 

Author Comment

by:deekakes
ID: 9719154
Thanks!
0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
Suggested Courses

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question