Solved

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

Posted on 2003-11-10
8
533 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 40 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
Independent Software Vendors: 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 60 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

Technology Partners: 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!

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
C++ assignment question 7 267
FMX TCameraComponent Problem 2 92
Beginner to Unreal Engine 4 5 104
learn programming 8 66
Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

740 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