A
Alex Vinokur
Functor-parameters in the for_each() and transform() algorithms are passed by value.
Might it make sense to have also algorithms for_each2() and transform2()
which pass Functor-parameters by non-const reference?
Here is some program which demonstrates probable necessity
in such forms of for_each() and transform().
====== C++ code : File foo.cpp : BEGIN ======
#include <vector>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <iterator>
using namespace std;
#define MAX_VALUE(x,y) ((x) > (y) ? (x) : (y))
class Foo
{
friend ostream& operator<< (ostream& os, const Foo& ioo);
private :
int sum_;
vector<int> vect_;
public :
Foo (vector<int> x, vector<int> y) : sum_ (0)
{
const unsigned max_size = MAX_VALUE (x.size (), y.size ());
x.resize(max_size);
y.resize(max_size);
vect_.resize(max_size);
// ------ transform ------
transform (x.begin(), x.end(), y.begin(), vect_.begin(), *this);
cout << "sum_ = " << sum_ << " (after transform)" << endl;
cout << (*this) << endl;
// It seems that it is impossible to change sum_ through transform because
// 1) Foo copy constructor is called;
// 2) transform() doesn't return Functor-object
// -----------------------
// ------ for-each -------
for_each (vect_.begin(), vect_.end(), *this);
cout << "sum_ = " << sum_ << " (after for_each-1)" << endl;
cout << (*this) << endl;
// sum_ is not changed because
// 1) Foo copy constructor is called;
// 2) Foo value returned is not used
// -----------------------
// ------ for-each -------
*this = for_each (vect_.begin(), vect_.end(), *this);
cout << "sum_ = " << sum_ << " (after for_each-2)" << endl;
cout << (*this) << endl;
// sum_ is changed because
// * Foo value returned is used to change *this
// -----------------------
// ------ for-each -------
*this = for_each (vect_.begin(), vect_.end(), *this);
cout << "sum_ = " << sum_ << " (after for_each-3)" << endl;
cout << (*this) << endl;
// sum_ is changed because
// * Foo value returned is used to change *this
// -----------------------
}
int operator() (int n1, int n2)
{
sum_ += n1;
sum_ += n2;
return (n1 + n2);
}
void operator() (int n)
{
sum_ += n;
}
};
ostream& operator<< (ostream& os, const Foo& ioo)
{
ostringstream oss;
oss << "{ vect_ = ";
copy (ioo.vect_.begin(), ioo.vect_.end(), ostream_iterator<int> (oss, " "));
return os << oss.str() << "}" << endl;
}
int main ()
{
const int a1[] = {1, 2, 3, 4, 5};
const int a2[] = {10, 20, 30, 40, 50, 60, 70};
const vector<int> v1 (a1, a1 + sizeof(a1)/sizeof(*a1));
const vector<int> v2 (a2, a2 + sizeof(a2)/sizeof(*a2));
{ Foo (v1, v2);}
return 0;
}
====== C++ code : File foo.cpp : END ========
====== Compilation & Run : BEGIN ======
$ g++ -v
[---omitted---]
gcc version 3.3.1 (cygming special)
$ g++ foo.cpp
$ a
sum_ = 0 (after transform) // sum_ not changed
{ vect_ = 11 22 33 44 55 60 70 }
sum_ = 0 (after for_each-1) // sum_ not changed
{ vect_ = 11 22 33 44 55 60 70 }
sum_ = 295 (after for_each-2) // sum_ changed
{ vect_ = 11 22 33 44 55 60 70 }
sum_ = 590 (after for_each-3) // sum_ changed
{ vect_ = 11 22 33 44 55 60 70 }
====== Compilation & Run : END ========
--
=====================================
Alex Vinokur
mailto:[email protected]
http://mathforum.org/library/view/10978.html
news://news.gmane.org/gmane.comp.lang.c++.perfometer
=====================================
Might it make sense to have also algorithms for_each2() and transform2()
which pass Functor-parameters by non-const reference?
Here is some program which demonstrates probable necessity
in such forms of for_each() and transform().
====== C++ code : File foo.cpp : BEGIN ======
#include <vector>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <iterator>
using namespace std;
#define MAX_VALUE(x,y) ((x) > (y) ? (x) : (y))
class Foo
{
friend ostream& operator<< (ostream& os, const Foo& ioo);
private :
int sum_;
vector<int> vect_;
public :
Foo (vector<int> x, vector<int> y) : sum_ (0)
{
const unsigned max_size = MAX_VALUE (x.size (), y.size ());
x.resize(max_size);
y.resize(max_size);
vect_.resize(max_size);
// ------ transform ------
transform (x.begin(), x.end(), y.begin(), vect_.begin(), *this);
cout << "sum_ = " << sum_ << " (after transform)" << endl;
cout << (*this) << endl;
// It seems that it is impossible to change sum_ through transform because
// 1) Foo copy constructor is called;
// 2) transform() doesn't return Functor-object
// -----------------------
// ------ for-each -------
for_each (vect_.begin(), vect_.end(), *this);
cout << "sum_ = " << sum_ << " (after for_each-1)" << endl;
cout << (*this) << endl;
// sum_ is not changed because
// 1) Foo copy constructor is called;
// 2) Foo value returned is not used
// -----------------------
// ------ for-each -------
*this = for_each (vect_.begin(), vect_.end(), *this);
cout << "sum_ = " << sum_ << " (after for_each-2)" << endl;
cout << (*this) << endl;
// sum_ is changed because
// * Foo value returned is used to change *this
// -----------------------
// ------ for-each -------
*this = for_each (vect_.begin(), vect_.end(), *this);
cout << "sum_ = " << sum_ << " (after for_each-3)" << endl;
cout << (*this) << endl;
// sum_ is changed because
// * Foo value returned is used to change *this
// -----------------------
}
int operator() (int n1, int n2)
{
sum_ += n1;
sum_ += n2;
return (n1 + n2);
}
void operator() (int n)
{
sum_ += n;
}
};
ostream& operator<< (ostream& os, const Foo& ioo)
{
ostringstream oss;
oss << "{ vect_ = ";
copy (ioo.vect_.begin(), ioo.vect_.end(), ostream_iterator<int> (oss, " "));
return os << oss.str() << "}" << endl;
}
int main ()
{
const int a1[] = {1, 2, 3, 4, 5};
const int a2[] = {10, 20, 30, 40, 50, 60, 70};
const vector<int> v1 (a1, a1 + sizeof(a1)/sizeof(*a1));
const vector<int> v2 (a2, a2 + sizeof(a2)/sizeof(*a2));
{ Foo (v1, v2);}
return 0;
}
====== C++ code : File foo.cpp : END ========
====== Compilation & Run : BEGIN ======
$ g++ -v
[---omitted---]
gcc version 3.3.1 (cygming special)
$ g++ foo.cpp
$ a
sum_ = 0 (after transform) // sum_ not changed
{ vect_ = 11 22 33 44 55 60 70 }
sum_ = 0 (after for_each-1) // sum_ not changed
{ vect_ = 11 22 33 44 55 60 70 }
sum_ = 295 (after for_each-2) // sum_ changed
{ vect_ = 11 22 33 44 55 60 70 }
sum_ = 590 (after for_each-3) // sum_ changed
{ vect_ = 11 22 33 44 55 60 70 }
====== Compilation & Run : END ========
--
=====================================
Alex Vinokur
mailto:[email protected]
http://mathforum.org/library/view/10978.html
news://news.gmane.org/gmane.comp.lang.c++.perfometer
=====================================