Hello,
I am working on a program that must perform a certain task on numeric data stored in a file. The task is given by user input from a list of possible tasks.
The file has some particular format and I have already a loop that is able to read sequentially data from the file. The question is how to operate with the data inside the loop in an efficient way.
The straight forward way (which I did) is creating as many functions as tasks are defined, each function containing the same file reading loop but with a different part inside.
To give a simple example, let's say that I want to sum all the content of the file -
double Task1(string &filename) {
-
// Opening part of the reading loop
-
// Code to operate on one element at a time and perform task 1
-
// Closing part of the reading loop
-
}
-
-
double TaskSum(string &filename) {
-
-
double sum = 0;
-
-
// Opening part of the reading loop Identical!!!
-
// the value of the last read element is stored in el
-
-
sum += el;
-
-
// Closing part of the reading loop Identical !!!
-
-
return sum;
-
}
-
-
And this for all tasks.
However, this is a nightmare to maintain and to expand. It will be also very annoying to perform the same tasks in other file type. That's why I would like to use function objects to do it. However, I am not sure how to do it in an appropriate way. The tasks that I need to perform most of the time need to keep some persistent information. Going back to my example before, Is the following code the most efficient way to do it using function objects? Will the performance be the same as the previous case? -
class tasks
-
{
-
public:
-
-
virtual void do(double el)=0;
-
virtual double result()=0;
-
};
-
-
-
-
class sumtask : public tasks
-
private:
-
double current;
-
-
public:
-
-
sumtask(): current(0) {} ;
-
void do(double el) { current += el; };
-
double result() { return current; };
-
-
};
-
-
-
-
void Task(string &filename, tasks &t) {
-
// Opening part of the reading loop Identical!!!
-
// the value of the last read element is stored in el
-
-
t.do(el);
-
-
// Closing part of the reading loop Identical !!!
-
return t.result();
-
}
-
-
-
int main(int argc, char* argv[]) {
-
string f = "file.bin";
-
sumtask t;
-
double result = Task(f, t);
-
}
-
-
I am using c++ compiled with gcc 4.0.1.
Thanks in advance,
Hernán
9 1839
I'm not sure what you mean by function objects since you don't use them in your example; function objects or functors overload operator(). It seems like you need to come up with a suitable abstraction for the file and the task so that the internals of the file abstraction can change depending on the file type independently to its interface as used by the task, which can then treat all file objects in the same way.
JosAH 11,448
Recognized Expert MVP
Remove the reading of the file part from your tasks and read up on the 'strategy'
pattern. Basically you want to do something with a sequence of numbers. Define
an abstract class Task that represents the number processing: -
public:
-
void preprocess() = 0;
-
void process(double x) = 0;
-
double postprocess() = 0;
-
All your 'concrete' tasks inherit from this abstract class and implement the
methods mentioned above.
Define a 'driver' class that does the file reading; the driver class is passed one
or more task class. While reading those numbers it activates the methods
defined in the task class.
Basically your driver class doesn't know what task it calls and the task(s) doesn't
know where these numbers come from but both do what they have to do. You
can call your driver class with different tasks without changing any code at all.
This is the strategy pattern in a nutshell.
kind regards,
Jos
I'm not sure what you mean by function objects since you don't use them in your example; function objects or functors overload operator(). It seems like you need to come up with a suitable abstraction for the file and the task so that the internals of the file abstraction can change depending on the file type independently to its interface as used by the task, which can then treat all file objects in the same way.
Thanks for the answer. This is exactly one of the problems. All examples that I have seen overloading operator() involve operations without memory, they do what they have to do in the current element and they do not remember anything of the past. Which is the efficient way to define a functor with state?
Thanks,
Hernan
Hi Jos,
Thanks for the reply. I tried your idea and is working fine. I wrote it using iterators so I can also use vectors or other STL containers.
As I pointed out in my other reply, I still would like to know how to implement efficient functors with state. Please do not close the thread.
Thanks,
Hernan
JosAH 11,448
Recognized Expert MVP
Thanks for the reply. I tried your idea and is working fine. I wrote it using iterators so I can also use vectors or other STL containers.
As I pointed out in my other reply, I still would like to know how to implement efficient functors with state. Please do not close the thread.
There's no reason at all to close this thread; it's a nice change compared to. all
the crap that is posted in here ;-)
A functor is just a class that overloads the operator() operator, so you're free to
do in that method whatever you want. I don't see the problem. Care to elaborate?
kind regards,
Jos
Which is the efficient way to define a functor with state?
I don't see why you can't have a functor class with data members, then objects of that class will be function objects which retain a state. If you need to share a state across all function objects of a certain class, then you can use a static member. This being said, I don't see how function objects are really relevant to your specific problem; implementing the suggestions in post#3 should do it.
Thanks for all the comments and suggestions. My problem is not how to do a specific task, but how to do it in a maintainable and efficient (fast executing code) way.
While trying to understand what was bothering me, I found (again) something that I read sometime ago (and I forgot because I never used it) in Stroustrup faq
class Sum {
int val;
public:
Sum(int i) :val(i) { }
operator int() const { return val; } // extract value
int operator()(int i) { return val+=i; } // application
};
Note that a function object with an inline application operator inlines beautifully because there are no pointers involved that might confuse optimizers.
What I do not know is how to write function objects (or other classes) in a way that the mentioned optimization always take place. Of course I can profile (and indeed I do) but it would be nice to have some a priori guidelines.
Let me give another example. Let's say I need to populate a vector (vOut) with calculations that come from subsets of another one (vIn). How the subsets are defined are part of my outer loop and it is the same for all tasks. What to do with the subset changes from task to task.
So: -
void task(vector<double> &vIn, vector<double> &vOut, tasks &t) {
-
-
// Outer Loop.
-
// The following variables are updated in each iteration
-
// i is the iteration index
-
// start is the iterator of vIn that define the start of the subset
-
// end is the iterator of vIn that define the end of the subset
-
-
vOut[i] = t(start, end);
-
-
// End of the outer loop
-
-
}
-
-
If t is an STL function like accumulate, the resulting binary will be the same as if I had written the code to do this operation directly inside the loop. How can I write function that keep this characteristic? For example, Will the following task also be inlined? -
class sometask {
-
double val;
-
vector <double> v;
-
public:
-
sometask (double i) :val(i) { }
-
-
operator double() const {
-
return val;
-
}
-
-
double operator()(iterator start, iterator end ) {
-
vector <double> tmp;
-
set_difference(start, end, v.begin(), v.end(), tmp);
-
v.swap(tmp);
-
return val+=accumulate(v.begin(), v.end());
-
}
-
};
-
Regards,
H
hi how are you?????
i hope to u all the best in your life....
please i want course in java (console application)
thanks
JosAH 11,448
Recognized Expert MVP
hi how are you?????
i hope to u all the best in your life....
please i want course in java (console application)
thanks
1) This is the C and C++ forum;
2) you're hijacking someone else's thread; that is rude.
kind regards,
Jos (moderator)
Sign in to post your reply or Sign up for a free account.
Similar topics |
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...
|
by: AngleWyrm |
last post by:
I have created a new container class, called the hat.
It provides random selection of user objects, both with and without
replacement, with non-uniform probabilities. Uniform probabilities are a
degenerate case, and can also be stored.
Here's the web-page, with complete source, illustration, and example usage.
Take a look-see, and post your critique!
http://home.comcast.net/~anglewyrm/hat.html
|
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.
|
by: Matthias |
last post by:
Hello,
I basically want to implement a general resource manager which should have
a caching and a loading policy so that I can exchange those. Here's some
example code of how it should work:
ResourceManager< SimpleCachingPolicy<Image, SimpleImageLoader> > imageMgr;
ResourceManager< SimpleCachingPolicy<Sound, SimpleSoundLoader> > soundMgr;
imageMgr.Load(filename, 1234);
|
by: Fraser Ross |
last post by:
Functors taking 1 argument for operator() should inherit from
unary_function and those with 2 arguments should inherit from
binary_function. If a functor has zero arguments for its operator()
should it inherit from anything to make it adaptable? I've not heard of
anything before which is surprising. If books don't talk about it then
its an unanswered question to many people. Maybe its adaptable without
inheriting anything, which would...
| |
by: michael.lesniak |
last post by:
Hello,
I'm learning C++ for a couple of days and play a bit with the
algorithms provided in the STL. One thing I don't understand is the
fact that classes inherited of functors have to be defined using
structs.
The code
template<class type> struct Print : public unary_function<type, void> {
|
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;}
};
|
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);
|
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...
|
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look !
Part I. Meaning of...
|
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed.
This is as boiled down as I can make it.
Here is my compilation command:
g++-12 -std=c++20 -Wnarrowing bit_field.cpp
Here is the code in...
| |
by: Hystou |
last post by:
Overview:
Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
|
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...
|
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, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own....
Now, this would greatly impact the work of software developers. The idea...
|
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...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
|
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
| |
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...
| |