473,466 Members | 1,351 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Re: polymorphic sorting functors

* Jerry Coffin <jc*****@taeus.com>:

[ ... using std::sort ]
>Is there still a way to do this without using templates?

Sure -- you can use a smart pointer class of some sort, which can be
passed by value, and still point at derived objects.

The big question would be why you want to do this -- you haven't said
why you want to rule out templates, but unless your code is doing
something a lot different from what you've shown, a template will make
simplify your code considerably.
My question was mostly out of curiosity. I've been working with C++ for about
half a year now, and I came across several occasions where my first approach
was to use polymorphism, but it did not work (could not write compilable code
that would express what I meant). In many of these cases, using templates was
a solution. In fact, I cannot recall any major issue where polymorphism was a
solution. Now I wanted to review these cases to see if I missed something.

In the case at hand, it looks like polymorphism really is the inferior
approach. Templates look better. There is, however, a third alternative: give
my function sort_it() a similar interface to that of std::sort(), so that I
can pass any comparison functor to it (by value). Maybe someone can point out
to me how to accomplish that. Thank you!

Jun 27 '08 #1
2 2610
In article <g3**********@news.albasani.net>, st******@mail.uni-kiel.de
says...

[ ... ]
In the case at hand, it looks like polymorphism really is the inferior
approach. Templates look better. There is, however, a third alternative: give
my function sort_it() a similar interface to that of std::sort(), so that I
can pass any comparison functor to it (by value). Maybe someone can point out
to me how to accomplish that. Thank you!
That could make sense if you passed the comparison function by
_reference_ instead of value. If you pass it by value, I don't see the
point, since you just end up with essentially a clone of std::sort.

As far as the basic point of polymorphism goes, it's mostly for
situations where you don't know until _runtime_ exactly what type of
object you're going to work with. The most obvious case is a collection
that's heterogenous, so different objects in the collection need to act
in different ways to get the correct behavior.

Another type of situation is where the polymorphic objects are
essentially similar to device drivers. For example, you might have a
database front-end that can talk to various different kinds of database
servers. From the viewpoint of the front-end, any server (that can meet
its requirements) is the same, but you still need some customized pieces
of code to allow that common interface to talk to the individual
servers, and you do that by having objects to talk to the servers, and
virtual functions to define the interface.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jun 27 '08 #2
L. Kliemann schrieb:
* Thomas J. Gritzan <ph*************@gmx.de>:
>If you want to change the sorting behaviour at run-time, you could pass
a tr1::function object to std::sort.

Great! I'd never heard of tr1 before, but it seems to be a solution.
tr1 will be part of the coming C++ standard. Most parts of it were
developed and were/are part of the Boost library. Both tr1 and Boost are
worth to know.
This code works (using gcc 4.2.4, produced no warnings with -Wall and
-Wextra):
Some comments:
>
#include <iostream>
#include <vector>
#include <algorithm>
#include <tr1/functional>

using namespace std;

typedef tr1::function <bool (int, int)func_t;

class cmp_base : public std::binary_function<int, int, bool{
public:
virtual bool operator()(int i, int j) = 0; };
class cmp_inc : public cmp_base {
public:
virtual bool operator()(int i, int j) { return i<j; } };
class cmp_dec : public cmp_base {
public:
virtual bool operator()(int i, int j) { return i>j; } };
You don't need a hierarchy with virtual functions. You can contruct a
tr1::function object with a simply functor (class with operator()) or
even a normal function. tr1::function works internally with virtual
functions and will dispatch the call to the currently assigned function
or functor.

But be aware that this run-time dispatch will disable some compiler
optimization, like inlineing the comparator function into the sort
algorithm. It's not a problem unless you have many objects to sort and
you need speed.
void sort_it(vector<int*v, func_t cmp) {
sort(v->begin(), v->end(), cmp); }
Prefer pass by reference:

void sort_it(vector<int>& v, const func_t& cmp) {
sort(v.begin(), v.end(), cmp);
}

Pointers have additional complexity that's not needed in this case.
Pointers can be null, they can be reseated, you can do arithmetics with
them. Prefer to use pointers only when you need them.

I would also pass the comparator by (const) reference to avoid a copy.
It is a kind of microoptimization, but a common one.
int main(void) {
vector<intv;
v.push_back(10);v.push_back(1);v.push_back(20);
cmp_dec cmp1;
sort_it(&v, cmp1);
cout << "decreasing:" << endl;
for (unsigned int i=0; i<v.size(); ++i) { cout << v.at(i) << endl; }
cmp_inc cmp2;
sort_it(&v, cmp2);
cout << "increasing:" << endl;
for (unsigned int i=0; i<v.size(); ++i) { cout << v.at(i) << endl; }
return 0; }
In general, if you want others to read your code, please insert more
whitespace/newlines. This code might be compact formatted, but it is
horrible to read it.

--
Thomas
Jun 27 '08 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Koen | last post by:
Hi! I have a vector containing the following: vector<Base*> theVector; theVector.push_back(new Der1()); theVector.push_back(new Der1()); theVector.push_back(new Der2());...
0
by: red floyd | last post by:
Disclaimer: VS.NET 2003 (haven't checked any other compiler). I'm writing functors for my classes. Because the objects in my containers are large, I'm making my functors take const T& parameters....
2
by: nsgi_2004 | last post by:
Hi, I have been learning about functors and at first everything was clear. Make a class and overload operator () so that an object of the functor can be thought of as a function. However, I...
20
by: verec | last post by:
One problem I've come accross in designing a specific version of auto_ptr is that I have to disntiguish between "polymorphic" arguments and "plain" ones, because the template has to, internally,...
0
by: SvenMathijssen | last post by:
Hi, I've been wrestling with a problem for some time that ought to be fairly simple, but turns out to be very difficult for me to solve. Maybe someone here knows the answer. What I try to do is...
4
by: tryptik | last post by:
Hello all, I have a question about iterators. I have a container of functors that operate on an std::string. The functors go something like this: class Functor { std::string...
2
by: Jon Slaughter | last post by:
I'm trying to mess with functors and the way I want it to work is that when I create a functor it will automatically add itself to an array. The attached code demonstrates what I mean. The...
8
by: Angelwings | last post by:
Hi everyone, I've to write my own definition of a BST with polymorphic data, as an university course project. I have troubles about comparing data when it's defined as polymorphic pointer. In my...
4
by: Christopher | last post by:
I used to just use a plain old function pointer is a call to std::sort. My colleagues are telling me that I need to use a "functor". Ok, I google and see that a functor is a class with a public...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.