Re: Unary functor on algorithm using copy constructor
On Jul 8, 6:50 pm, Dijkstra <pepi...@gmail.com> wrote:
First, this is the code I'm using to expose the problem:
------------------------------------------------------------------
#include <functional>
#include <string>
#include <iostream>
using namespace std;
struct space_comparer : public unary_function<char, bool> {
mutable argument_type __lastChar;
space_comparer()
{
__lastChar = 'X';
cout << "ctor() called and lastChar is '" << __lastChar <=
< "'" <<
endl;
}
space_comparer(const space_comparer &__src)
{
cout << "copy ctor() called setting lastChar to 'Y'" << e=
ndl;
__lastChar = 'Y';
}
result_type operator ()(const argument_type c) const
{
cout << "[" << __lastChar << " | " << c << "]" << endl;
__lastChar = c;
return ::isspace(c);
}
};
main()
{
string cad1;
string cad2;
const space_comparer instance;
cad1 = "cpp";
remove_copy_if(cad1.begin(), cad1.end(), back_inserter(cad2),
instance );
remove_copy_if(cad1.begin(), cad1.end(), back_inserter(cad2),
instance );
remove_copy_if(cad1.begin(), cad1.end(), back_inserter(cad2),
instance );
return 0;}
---------------------------------------------------------------
OK, so the meaning of all that is to use a unary function with
a persistent "state", so that the "space_comparer" works by
using previous values. My problem is that the "remove_copy_if"
algorithm, and I think all algorithms, use a copy.
The predicate object is passed by copy, so all they have is a
copy to begin with; they have no means of accessing the orginal
object.
I mean, suppose this call:
remove_copy_if(cad1.begin(), cad1.end(), back_inserter(cad2),
space_comparer() );
This works by constructing a new "space_comparer" functor
object and using its instance for all the algorithm lifetime.
What I like to do is use an actual instance as the predicate,
so that it can mantain a state across algorithm calls.
The problem is that in order to do that, the algorithm would
have to declare the predicate parameter as a reference. A const
reference, if the above is to work.
remove_copy_if(cad1.begin(), cad1.end(), back_inserter(cad2),
instance );
I supposed the above call would reuse the "instance" of the
object functor, which indeed does. But it does a temporary
copy of the object and it works with it, leaving the original
instance untouched. The output of the above code is:
-----------------------------------------------------------------
ctor() called and lastChar is 'X'
copy ctor() called setting lastChar to 'Y'
[Y | c]
[c | p]
[p | p]
copy ctor() called setting lastChar to 'Y'
[Y | c]
[c | p]
[p | p]
copy ctor() called setting lastChar to 'Y'
[Y | c]
[c | p]
[p | p]
-----------------------------------------------------------------
Which is what is required by the standard.
But, the expected output needs to be like this:
-----------------------------------------------------------------
ctor() called and lastChar is 'X'
[X | c]
[c | p]
[p | p]
[p | c] <<--- Note previous state of "lastChar"
[c | p]
[p | p]
[p | c] <<--- Note previous state of "lastChar"
[c | p]
[p | p]
-----------------------------------------------------------------
I don't know if this is at all possible. I already tried with
"mem_func" and such techniques, but to no avail...
Please, I'm not so STL literate, so bear with me. :-)
A long time ago, there was a saying: "The solution to every
problem is an additional level of indirection." Change your
space_comparer to contain a char* as member, provide a
constructor which takes an char* as argument, and use that,
declaring the char before the predicate.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34