From 2329502722539006882
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: f78e5,eaf633a917dfd8af,start
X-Google-Attributes: gidf78e5,public
X-Google-ArrivalTime: 2003-11-06 22:38:28 PST
Path: archiver1.google.com!news2.google.com!news.maxwell.syr.edu!kibo.news.demon.net!mutlu.news.demon.net!demon!mail2news.demon.co.uk!devnull
From: alexvn@bigfoot.com ("Alex Vinokur")
Newsgroups: comp.std.c++
Subject: Passing functor-parameters in for_each() and transform()
Date: Fri, 7 Nov 2003 06:38:26 +0000 (UTC)
Lines: 156
Approved: fjh@cs.mu.oz.au (Fergus Henderson , moderator of comp.std.c++)
Message-ID: <bo8jui$19aso0$1@ID-79865.news.uni-berlin.de>
X-Trace: mail2news.demon.co.uk 1068187106 2441 10.0.0.1 (7 Nov 2003 06:38:26 GMT)
X-Complaints-To: abuse@demon.net
NNTP-Posting-Date: Fri, 7 Nov 2003 06:38:26 +0000 (UTC)
X-Received: from mulga.cs.mu.oz.au ([128.250.1.22])
	by news.demon.co.uk with esmtp (Exim 4.12)
	id 1AI0GG-0000dE-00
	for mail2news@news.news.demon.net; Fri, 07 Nov 2003 06:38:25 +0000
X-Received: from localhost (localhost [[UNIX: localhost]]) by mulga.cs.mu.OZ.AU
	id RAA11858; Fri, 7 Nov 2003 17:38:20 +1100 (EST)
X-Authentication-Warning: mulga.cs.mu.OZ.AU: fjh set sender to devnull@stump.algebra.com using -f
X-Path: comp-std-cpp-robomod!not-for-mail
X-Robomod: STUMP, ichudov@algebra.com (Igor Chudov)
X-Delivered-To: std-c++@ucar.edu
X-Newsgroups: comp.std.c++
X-Reply-To: "Alex Vinokur" <alexvn@connect.to>
X-Orig-NNTP-Posting-Host: pop03-2-ras5-p17.barak.net.il (212.150.100.17)
X-Orig-X-Trace: news.uni-berlin.de 1067963156 43348736 212.150.100.17 (16 [79865])
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 6.00.2800.1106
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1106
X-Spam-Status: No, hits=-4.3 required=5.0
	tests=BAYES_10,PRIORITY_NO_NAME
	version=2.55
X-Spam-Checker-Version: SpamAssassin 2.55 (1.174.2.19-2003-05-19-exp)
Xref: archiver1.google.com comp.std.c++:370


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:alexvn@connect.to
     http://mathforum.org/library/view/10978.html
     news://news.gmane.org/gmane.comp.lang.c++.perfometer
   =====================================




---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]



