C++ compilation error when I use predicate friend function in the std::sort()

Hi,

Can anyone tell me why the following program is giving compiler error when I use a friend function of a class as the comparison predicate for the third parameter of std::sort() algorithm? How to correct it, keep the 'friend' intact?

#include <iostream>
#include <vector>
#include <list>
#include <algorithm>

using namespace std;

class A {
    inline friend bool comp(const A& o1, const A& o2) {
        return o1.data < o2.data; // binary predicate function
    }

    inline friend bool operator < (const A& o1, const A& o2) {
        return o1.data < o2.data; // overloaded 'operator < ()' function
    }
public:
    int data;
    A(int i = 0) : data(i) { }
    inline int getVal() const { return data; }
};

struct great {
    bool operator() (const A& lx, const A& rx) const {
        return lx.data < rx.data;
    }
};

int main() {
    A a(60), b(20), c(50);
    std::vector<A> v;
    std::list<A> ll;

    v.push_back(a);
    v.push_back(b);
    v.push_back(c);

    std::sort(v.begin(), v.end(), comp); // std::sort() called with predicate
    std::sort(v.begin(), v.end(), great());

    for (vector<A>::const_iterator itr1 = v.begin(); itr1 != v.end(); ++itr1) {
        cout << (*itr1).getVal() << endl;
    }

    ll.push_back(a);
    ll.push_back(b);
    ll.push_back(c);

    ll.sort(); // internally calls overloaded operator < ()

    for (list<A>::const_iterator itr2 = ll.begin(); itr2 != ll.end(); ++itr2) {
        cout << (*itr2).getVal() << endl;
    }

    list.sort(comp); // uses predicate in the sort

    for (list<A>::const_iterator itr3  = ll.begin(); itr3 != ll.end(); ++itr3) {
        cout << (*itr3).getVal() << endl;
    }
}

Solved the problem myself, by adding the declaration outside the class and before main() like this.. :slight_smile:

inline bool comp(const A&, const A&); 

If we miss this, the function is not visible inside sort()

---------- Post updated 03-19-12 at 03:53 PM ---------- Previous update was 03-18-12 at 07:33 PM ----------

Can anyone help me to convert the above program to a template version? I am getting stuck in converting the function pointer 'comp', predicate function of sort() as a template. I am getting undefined reference.

---------- Post updated 03-20-12 at 11:24 AM ---------- Previous update was 03-19-12 at 03:53 PM ----------

In the following program why my std::find() algorithm is not able to search for the vector container element (7,9) though it is present there?
How to correct it?

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>

using std::vector;
using namespace std;

class CTest {
public:
     CTest(int _xx, int _yy) : x(_xx), y(_yy) {}
     int x, y;
};

int main() {
     vector<CTest*> vt;  // create an array of CMyClass object pointers

     cout << "initial capacity: " << vt.capacity() << endl; // Ans: 0
     vt.reserve(5); // causes reallocation manually, control invalidation of iterators
     cout << "present capacity: " << vt.capacity( ) << endl; // Ans: 5

     vt.push_back(new CTest(2, 4)); // dynamically add some elements, vector grow
     vt.insert(vt.begin(), new CTest(4, 6)); // stored in the index pos 0, replaces 2, 4

     vector<CTest*>::iterator itr1 = vt.begin() + 2; // stores in the index pos 1
     vt.insert(itr1, new CTest(6, 8));

     vt.push_back(new CTest(7, 9)); // pop_back() decreases size

     cout << "vector size: " << (int)vt.size() << endl; // Ans: vector size: 3
    /* always vector has 1 extra size */
     cout << "first x elem: " << vt[0]->x << endl; // Ans: 4
     cout << "first y elem: " << vt[0]->y << endl; // Ans: 6


     vector<CTest*>::iterator it; // stores in the index pos 1
     it = find(vt.begin(), vt.end(), new CTest(7, 9));
     if (it == vt.end())
         cout << "Could not find 7 in the vector" << endl;
     else
         cout << "Have found 7 in the vector" << endl;

     vector<CTest*>::iterator itr2 = vt.begin() + 2; // 2nd element iter
     delete *itr2;        // free the memory occupied by the 2nd element, here (2, 4)
     vt.erase(itr2);    // remove the 2nd element from the array, CTest (2, 4)

     vector<CTest*>::iterator itPos = vt.begin() /* + 0 */ ;
     for(; itPos < vt.end(); itPos++) {
         printf("Coordinates at %d is : (%d, %d)\n", (int)(itPos - vt.begin()) ,
                                                                       (*itPos)->x, (*itPos)->y);
         delete *itPos;  // deleting the memory for each and every element in the array
     }
     vt.clear();  // clear all elements from the array
}