0

My C++ is a little rusty as of late. Can one of you gurus help me define a SORT predicate, for a Container Class, with a template parameter which it self is a another class.

template <class Element>
class OrderedSequence
// Maintains a sequence of elements in
// ascending order (by "<"), allowing them to be retrieved
// in that order.
{


 public:
 // Constructors
 OrderedSequence();

 OrderedSequence(const OrderedSequence<Element>&);

 // Destructor
 ~OrderedSequence(); // destructor

 OrderedSequence<Element>& operator= (const OrderedSequence<Element>& ws);

 // Get an element from a given location
 const Element& get (int k) const;



// Add an element and return the location where it
// was placed.
int add (const Element& w);

bool empty() const      {return data.empty();}
unsigned size() const   {return data.size();}


// Search for an element, returning the position where found
// Return -1 if not found.
int find (const Element&) const;


void print () const;

bool operator== (const OrderedSequence<Element>&) const;
bool operator< (const OrderedSequence<Element>&) const;

private:

std::vector<Element> data;

};

So, this class receives a template parameter which is a STRUCT with std::string member variable.

I would like to define a simple sort predicate, so that I can call : std::sort(data.begin(), data.end(), sort_xx) after performing a : data.push_back() within the add() member function of the class above.

How do I do it? I am not using C++ 11 - just plain old C++.

Template parameter Element.. gets translated to:

struct AuthorInfo 
{
string name;
Author* author;

AuthorInfo (string aname)
   : name(aname), author (0)
 {}

bool operator< (const AuthorInfo&) const;
bool operator== (const AuthorInfo&) const;
};

bool AuthorInfo::operator< (const AuthorInfo& a) const
{
   return name < a.name;
}

bool AuthorInfo::operator== (const AuthorInfo& a) const
{
  return name == a.name;
}
Cosmic OM...
  • 181
  • 4
  • 14
  • How exactly do you want to order the `Element` objects? (Also, plain old C++ *is* C++11. You probably mean you're still limited to C++03.) – aschepler Jun 11 '14 at 23:32
  • Yes sir, my friend (whose code this is) is only using C++03. I don't program any longer, so have lost touch a bit sir. I wish to order the Element in Ascending order. And element is a STRUCT with a std::string . Shouldn't be too hard for someone who program in C++ regularly. Cheers and Peace. – Cosmic OM... Jun 11 '14 at 23:42
  • 1
    You should be using the stock `std::less<>` for your predicate, but honestly, that predicate shouldn't be for `sort` because you shouldn't be using it in the first place. It should be for [`upper_bound`](http://en.cppreference.com/w/cpp/algorithm/upper_bound) , which you should be using to locate the proper insertion point in the first place rather than resorting the entire sequence with each item you slap on the end. – WhozCraig Jun 12 '14 at 01:44
  • @WhozCraig. I understand your point about the sorting logic. Thanks for that. I have only just looked at this code my self. Will look it to it soon. Thanks for your observations. – Cosmic OM... Jun 12 '14 at 10:12
  • So in summary. It would seem that the OOD is good in this project- enough for me to NOT need a predicate after all- at least from a basic, functional (needs) perspective. the sort function didn't need a predicate, as the AuthorInfo's overloaded < op, already took care of that- as it should. Blessings to All who helped me. Maiterya-BuddhaLight.. – Cosmic OM... Jun 12 '14 at 11:33

1 Answers1

0

What can use std::find_if, if you need a custom predicate.

To define a Predicate ala C++03 :

// For find()
struct MyPredicate
{
public:
  explicit MyPredicate(const std::string name) name(name) { }

  inline bool operator()(const Element & e) const { return e.name == name; }

private:
  std::string name;
};

// Assuming you want to lookup in your vector<> member named "data"
std::find_if(data.begin(), data.end(), MyPredicate("Luke S."));

// To sort it, its exactly the same but with a Sort comparer as the predicate:
struct MySortComparator
{
 bool operator() (const Element& a, const Element& b) const
 {
    return a.name < b.name;
 }
};

std::sort(data.begin(), data.end(), MySortComparator());

// Or you can style sort Author without predicates if you define `operator<` in the `Element` class :
std::sort(data.begin(), data.end())

If you can use C++11, you can simply use a lambda :

std::find_if(data.begin(), data.end(), [](const Element & e) -> bool { return e.name == "Luke S."; });

EDIT:

Now that you show Element I see that you already overloaded operator== in Author, so you could also do :

int find (const Element& e) const
{
  std::vector<Element>::iterator iter = std::find(data.begin(), data.end(), e);
  return std::distance(data.begin(), iter);
}
quantdev
  • 23,517
  • 5
  • 55
  • 88
  • I've posted the Element parameter translation above. Cheers. – Cosmic OM... Jun 11 '14 at 23:59
  • so simply replace my `GetString()` , by `name` ? edited – quantdev Jun 12 '14 at 00:04
  • Also, I am actually looking to SORT the vector(called) data- using a simple sort predicate. thanks. – Cosmic OM... Jun 12 '14 at 00:06
  • Yup, I am aware of the GetString() function and its usage. My issue is that this std::sort is being called inside a member function of OrderedSequence, and am trying to get the semantics of C++ preicates right, in the context of custom container classes- which is what this class essentially is. – Cosmic OM... Jun 12 '14 at 00:08
  • I edited (+ sort) : the semantics of a standard predicate are what I described: Does that answer your question ? – quantdev Jun 12 '14 at 00:13
  • Thank you quantdev. I really appreciate your time and efforts. I believe you have answered my question. I will try it out in the morning and get back to you (and mark the answer as right, which I'm sure it will be). Thank you for your patience with my overloaded mental and Spiritual operators. :) A++ to u for being persistent in helping me. – Cosmic OM... Jun 12 '14 at 00:19
  • 1
    `MyPredicate` is not a sort ordering. (The two-argument `sort` will work, though.) – aschepler Jun 12 '14 at 01:08
  • Thanks to quantdev. The solution to my problem was explained well, in terms of : the overloaded < operator in AuthorInfo and the ultra-simplified use of the std::sort algo without having to use a predicate- as (to quote quantdev): "// Or you can style sort Author without predicates if you define `operator<` in the `Element` class : std::sort(data.begin(), data.end())" Well done! and thanks for the optimization clues left by others too. – Cosmic OM... Jun 12 '14 at 11:31