473,403 Members | 2,071 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,403 software developers and data experts.

Function objects with state

Hello all,

When working with the STL, under what circumstances may I use a function
object that modifies its internal state from one call to the next? I know
this can be done with for_each<>(). I know it cannot be done if the function
object happens to be a predicate.

Is there a general rule that says when a function object can or cannot
modify state?

Thanks,
Dave
Jul 23 '05 #1
3 1772
Dave wrote:
Hello all,

When working with the STL, under what circumstances may I use a function
object that modifies its internal state from one call to the next? I know
this can be done with for_each<>(). I know it cannot be done if the function
object happens to be a predicate.

Is there a general rule that says when a function object can or cannot
modify state?

Thanks,
Dave


I'm not an expert, but... I don't know of any express prohibition
against a function with internal state, even if it is a predicate.
Indeed this is one of the benefits of using a function object.

Of course, you have to avoid doing silly things like changing the
comparison value of objects while stored in a sorted container. In my
own codes, I've often found it more useful to have a function object
that contains a pointer to some external data so that the external data
can be modified be an external element. (Hard to do otherwise since the
container will have its own copy of the function.)

HTH,
Mark
Jul 23 '05 #2

"Mark P" <no*@my.real.email> wrote in message
news:sL****************@newssvr21.news.prodigy.com ...
Dave wrote:
Hello all,

When working with the STL, under what circumstances may I use a function
object that modifies its internal state from one call to the next? I know this can be done with for_each<>(). I know it cannot be done if the function object happens to be a predicate.

Is there a general rule that says when a function object can or cannot
modify state?

Thanks,
Dave


I'm not an expert, but... I don't know of any express prohibition
against a function with internal state, even if it is a predicate.
Indeed this is one of the benefits of using a function object.

Of course, you have to avoid doing silly things like changing the
comparison value of objects while stored in a sorted container. In my
own codes, I've often found it more useful to have a function object
that contains a pointer to some external data so that the external data
can be modified be an external element. (Hard to do otherwise since the
container will have its own copy of the function.)

HTH,
Mark


Oh, I agree that *having* internal state is not bad in any case. It's just
that in some cases, that state should never be *changed*. A case in point
would be a predicate. In other cases, it is OK to let the functor change its
state from one call to the next.
Jul 23 '05 #3
Dave wrote:
Hello all,

When working with the STL, under what circumstances may I use a function
object that modifies its internal state from one call to the next? I know
this can be done with for_each<>(). I know it cannot be done if the
function object happens to be a predicate.
I do not understand why it *cannot be done* if the function object is a
predicate. Consider:

#include <cstdlib>
#include <algorithm>
#include <vector>
#include <iostream>
#include <iterator>

struct RandomPredicate {

RandomPredicate ( unsigned long _seed ) {
std::srand( _seed );
}

bool operator() ( int ) {
return( std::rand() < ( RAND_MAX >> 2 ) );
}

}; // RandomPredicate

int main ( void ) {
RandomPredicate P ( 1234 );

std::vector< int > i_vect;
for ( unsigned i = 0; i < 20; ++i ) {
i_vect.push_back( i );
}
std::ostream_iterator<int> o_iter ( std::cout, " " );
std::remove_copy_if( i_vect.begin(), i_vect.end(), o_iter, P );
}

Here a predicate object is used to make a random selection. Note that
std::remove_copy_if does not assume that the calling the same predicate
twice on the same object will yield identical results. At least, I did not
see that assumption stated in the standard.
Or consider this:

#include <cstdlib>
#include <algorithm>
#include <vector>
#include <iostream>
#include <iterator>

template < typename T >
struct CountingCompare {

// NOTE: [static to avoid hassle]
/*
std::sort receives a copy of the function object. To ensure that
we see the counter afterwards, we either have to use a pointer
(hassle) or a static variable (quick hack).
*/
static unsigned long count;

bool operator() ( T const & a,
T const & b ) const {
++ count;
return( a < b );
}

}; // CountingCompare

template < typename T >
unsigned long CountingCompare<T>::count = 0;

int main ( void ) {
CountingCompare<int> int_comp;
std::vector<int> i_vect;
for ( unsigned i = 0; i < 2000; ++i ) {
i_vect.push_back( i );
}
std::random_shuffle( i_vect.begin(), i_vect.end() );
std::sort( i_vect.begin(), i_vect.end(), int_comp );
std::cout<< "Sort needed " << int_comp.count << " comparisons\n";
}

Here, a statefull binary predicate is used to count how many comparisons
are done by std::sort. This works since the object still behaves like
an order relation. That is has a state, which changes, is irrelevant to the
algorithm.

Is there a general rule that says when a function object can or cannot
modify state?


No, those rules have to be stated for each algorithm / method seperately.

Best

Kai-Uwe Bux
Jul 23 '05 #4

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

Similar topics

4
by: richardclay09 | last post by:
Hi Can someone please write some "compare and contrast" notes for "Template functions vs. function objects"? When to use one and not the other? For example, the TF square_f does the same thing as...
38
by: Lasse Vågsæther Karlsen | last post by:
After working through a fair number of the challenges at www.mathschallenge.net, I noticed that some long-running functions can be helped *a lot* by caching their function results and retrieving...
16
by: Nikolay Petrov | last post by:
How can I return multiple values from a custom function? TIA
20
by: asdf | last post by:
True or false ?
28
by: Larax | last post by:
Best explanation of my question will be an example, look below at this simple function: function SetEventHandler(element) { // some operations on element element.onclick = function(event) {
7
by: VK | last post by:
I was getting this effect N times but each time I was in rush to just make it work, and later I coudn't recall anymore what was the original state I was working around. This time I nailed the...
7
by: DevNull | last post by:
Hi there everyone, I'm creating a very simple immediate mode command interpreter. The final purpose is to provide a pluggable control and command console for a MUD server I have written. The...
28
by: Jess | last post by:
Hello, It is said that if I implement a "swap" member function, then it should never throw any exception. However, if I implement "swap" non- member function, then the restriction doesn't...
3
by: AliRezaGoogle | last post by:
Dear Members, I have written a recursive function. It calls itself recursively. It is placed inside a thread. So I can easily suspend and resume the thread to suspend or resume the function as...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
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...

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.