473,769 Members | 7,272 Online
Bytes | Software Development & Data Engineering Community
+ 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 2632
In article <g3**********@n ews.albasani.ne t>, st******@mail.u ni-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_fun ction<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 microoptimizati on, 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
3725
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()); theVector.push_back(new Der2()); ....
0
1741
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. If I try std::bind2nd() with one of these classes, I get an error about a reference to a reference. What's the proper way to declare functors taking const T& parameters so that they play nicely with adapters? Would it be something like the...
2
1557
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 have seen in Effective STL, Scott passes normal functions into places that expect functors. I'm not sure how this works, as I thought functors had to be classes.
20
2229
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, cast to void *. Specifically, template <typename T> void f(T * t) { void * p = dynamic_cast<void *>(t) ; } will not compile if T isn't of a class that has somewhere at least
0
2581
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 sort the records in a plain-text index file based on certain columns. The index file consists of records and fields within the records. The individual fields are separated by semicolons, the records by newlines. The index file is loaded into memory...
4
2240
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 operator()(const std::string& s) {/*manipulate string*/; return newString;} };
2
1752
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 problem is that its a bit unsatisfactory and I'd like to improve it. In the constructor of TClassA Functors<TClassA, std::string*Functor = new Functors<TClassA, std::string>(this, &TClassA::Display);
8
1650
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 situation I've something like: class A {} class B : public A {} class C : public A {}
4
2750
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 method, operator () that does the comparison. Fine, no problem. What they fail to tell me is, what is the advantage to wrapping some comparison function in a class and calling it operator()? I also read that "functors" are supposed to be a...
0
9423
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10049
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
9865
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
7413
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 presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6675
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5309
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 last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5448
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3965
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 we have to send another system
3
2815
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.