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 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
"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.
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 This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
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...
|
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...
|
by: Nikolay Petrov |
last post by:
How can I return multiple values from a custom function?
TIA
|
by: asdf |
last post by:
True or false ?
|
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)
{
|
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...
|
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...
|
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...
|
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...
|
by: Charles Arthur |
last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
|
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
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
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...
|
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...
|
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,...
|
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,...
|
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,...
|
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...
| |