Topic: overloaded 'for_each


Author: "Ken Alverson" <Ken@Alverson.com>
Date: Fri, 21 Jun 2002 15:37:13 CST
Raw View
"Thorsten Ottosen" <nesotto@cs.auc.dk> wrote in message
news:aeviqk$212$1@sunsite.dk...
> And if anybody
> would ever wright a piece of code (God forbid) that
> somehow contained th   s text
>
> XX.begin(), XX.end()

I hate using the preprocessor, but you could #define all(XX) to be
"XX.begin(),XX.end()" and come pretty close without changing the
algorithms...

Ken


---
[ 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                       ]





Author: "Thorsten Ottosen" <nesotto@cs.auc.dk>
Date: Sat, 22 Jun 2002 17:04:57 GMT
Raw View
"Ken Alverson" <Ken@Alverson.com> wrote in message
news:af00ru$4cv$1@eeyore.INS.cwru.edu...
> "Thorsten Ottosen" <nesotto@cs.auc.dk> wrote in message
> news:aeviqk$212$1@sunsite.dk...
> > And if anybody
> > would ever wright a piece of code (God forbid) that
> > somehow contained th   s text
> >
> > XX.begin(), XX.end()
>
> I hate using the preprocessor, but you could #define all(XX) to be
> "XX.begin(),XX.end()" and come pretty close without changing the
> algorithms...
Yes. But what about calling the algortihms directly with the return value
from
a function without using a temporary?

Conatainer c = get_XX();
for_each( ALL(c), print );

could be

for_each( get_XX(),  print );

with a new overload.

-Thorsten
nesotto@cs.auc.dk



---
[ 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                       ]





Author: "Markus Mauhart" <markus.mauhart@nospamm.chello.at>
Date: 24 Jun 2002 02:30:05 GMT
Raw View
[outlook express refuses to intent your msg, so I've ommitted most of it]

"Daniel Frey" <daniel.frey@aixigo.de> wrote ...
>
> I think this should also be possible with the current version of
> for_each. This works, as the iterator is referenced through it's
> container. Sure there are problems when you try to make the iterator a
> typedef so several containers share the same iterator type, but this is
> a STL-implementation-specific problem.

Could you pls be more explicit, I dont understand this.

> I also wondered if the following
> idea could be used for your point about specializations for begin/end to
> work at compile-time:

IMHO an interesting idea, I'll try to summarize it:

Given:
MYCONT has rather slow normal iterators, especially the normal
usage pattern "algorithm (mycont.begin(), mycont.end(),..)" could be
significantly improofed when others would access MYCONT through
"algorithm (mycont,..)" which is a specialization provided by me.

Wanted:
Foraign code using the traditional pattern with begin()/end()
shall automatically map to my optimized algorithm versions
as soon as this code accesses MYCONT.

Your solution:
MYCONT::begin()/end() dont return MYCONT::iterator's but some type
transparently convertible to MYCONT::iterator; additionally I provide
inline versions of the interesing algorithms specialized for the
two MYCONT::begin/End/Iterator (dummy-)types which e.g. in the case of
"algorithm(MYCONT::beginIterator, MYCONT::endIterator)" ignore the
values but call my actual "algorithm(MYCONT,..)" optimized version.

Really interesting, allthough as you have pointed out maybe some
compatibility problems:

23.1, table 65 requires container::iterator as the return type
of begin()/end(), and IIRC this is a known problem for any
container that wanted to return some proxies from begin/end().

Another problem (or a consequence of this non-compliant behaviour
and of the fact that no conversions are really transparent)
might be that begin()/end() when used in arbitrary expressions
would need an additional conversion, that is it could break some
of that expressions.

Anyway, I'm neither a STL nor a conversion expert, so generally
I'd prefer to avoid this trick; maybe I'll use it; and maybe
my doku will say "do you a favour, use algorithm(cont,..)
instead of algorithm(cont.begin(),cont.end(),..)".


Markus.



---
[ 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                       ]





Author: Daniel Frey <daniel.frey@aixigo.de>
Date: Mon, 24 Jun 2002 08:53:08 GMT
Raw View
Markus Mauhart wrote:
>=20
> [outlook express refuses to intent your msg, so I've ommitted most of i=
t]

Why not use a mail-program instead of a virus-lab? ;)

> "Daniel Frey" <daniel.frey@aixigo.de> wrote ...
> >
> > I think this should also be possible with the current version of
> > for_each. This works, as the iterator is referenced through it's
> > container. Sure there are problems when you try to make the iterator =
a
> > typedef so several containers share the same iterator type, but this =
is
> > a STL-implementation-specific problem.
>=20
> Could you pls be more explicit, I dont understand this.

OK, but I have to admit that this won't be 100% compatible with the
current standard. To make a clean implementation, the iterator needs to
export its value_type, which currently isn't the case. See this code:

#include <iostream>
#include <typeinfo>
#include <vector>
#include <list>

template< typename value_type >
void for_each_impl( const value_type&, // Remove this parameter for v2
                    const typename std::vector< value_type >::iterator&
t,
                    const typename std::vector< value_type >::iterator&
u )
{
   std::cout << "Vector: " << typeid( value_type ).name() << std::endl;
}

template< typename value_type >
void for_each_impl( const value_type&, // Remove this parameter for v2
                    const typename std::list< value_type >::iterator& t,
                    const typename std::list< value_type >::iterator& u
)
{
   std::cout << "List: " << typeid( value_type ).name() << std::endl;
}

template< typename iterator >
inline void my_for_each( const iterator& t, const iterator& u )
{
   // v1: Dereferencing end() is not allowed!
   for_each_impl( *t, t, u );
  =20
   // v2: With proper support from the STL iterator:
   // for_each_impl< typename iterator::value_type >( t, u );
}

int main()
{
   std::vector< int > v;
   std::list< double > l;

   my_for_each( v.begin(), v.end() );
   my_for_each( l.begin(), l.end() );
}

Hope you get the idea...

> > I also wondered if the following
> > idea could be used for your point about specializations for begin/end=
 to
> > work at compile-time:
>=20
> IMHO an interesting idea, I'll try to summarize it:
>=20
> Given:
> MYCONT has rather slow normal iterators, especially the normal
> usage pattern "algorithm (mycont.begin(), mycont.end(),..)" could be
> significantly improofed when others would access MYCONT through
> "algorithm (mycont,..)" which is a specialization provided by me.
>=20
> Wanted:
> Foraign code using the traditional pattern with begin()/end()
> shall automatically map to my optimized algorithm versions
> as soon as this code accesses MYCONT.
>=20
> Your solution:
> MYCONT::begin()/end() dont return MYCONT::iterator's but some type
> transparently convertible to MYCONT::iterator; additionally I provide
> inline versions of the interesing algorithms specialized for the
> two MYCONT::begin/End/Iterator (dummy-)types which e.g. in the case of
> "algorithm(MYCONT::beginIterator, MYCONT::endIterator)" ignore the
> values but call my actual "algorithm(MYCONT,..)" optimized version.

Through derivation, begin_iterator ISA iterator. Sure there might be
special cases where this might be a problem and I haven't said that I
have the best solution ever. It's just an idea, another approach to
consider...

> Really interesting, allthough as you have pointed out maybe some
> compatibility problems:
>=20
> 23.1, table 65 requires container::iterator as the return type
> of begin()/end(), and IIRC this is a known problem for any
> container that wanted to return some proxies from begin/end().

Yes, I am aware of this. The question is, whether a type derived from
iterator qualifies as an iterator :)

> Anyway, I'm neither a STL nor a conversion expert, so generally
> I'd prefer to avoid this trick; maybe I'll use it; and maybe
> my doku will say "do you a favour, use algorithm(cont,..)
> instead of algorithm(cont.begin(),cont.end(),..)".

The basic question of this thread deals with a new STL-version, not the
current one. Thus, I think anything should be discussed which is not too
far from the current standard and which might improve things.

Regards, Daniel

--
Daniel Frey

aixigo AG - financial training, research and technology
Schlo=DF-Rahe-Stra=DFe 15, 52072 Aachen, Germany
fon: +49 (0)241 936737-42, fax: +49 (0)241 936737-99
eMail: daniel.frey@aixigo.de, web: http://www.aixigo.de

---
[ 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                       ]





Author: Daniel Frey <daniel.frey@aixigo.de>
Date: Mon, 24 Jun 2002 15:19:38 GMT
Raw View
Yes, I'm replying to myself. I just found out something new! :)

Daniel Frey wrote:
>=20
> OK, but I have to admit that this won't be 100% compatible with the
> current standard. To make a clean implementation, the iterator needs to
> export its value_type, which currently isn't the case. See this code:

The gcc 2.95.2 (and probably other versions) does export value_type for
'real' iterators, so a better implementation is this one:

#include <iostream>
#include <typeinfo>
#include <vector>
#include <list>

// implementation

template< typename value_type >
void for_each_impl( const typename std::vector< value_type >::iterator&
t,
                    const typename std::vector< value_type >::iterator&
u )
{
   std::cout << "Vector: " << typeid( value_type ).name() << std::endl;
}

template< typename value_type >
void for_each_impl( const typename std::list< value_type >::iterator& t,
                    const typename std::list< value_type >::iterator& u
)
{
   std::cout << "List: " << typeid( value_type ).name() << std::endl;
}

// dereference

template< typename T >
struct dereference
{ typedef typename T::value_type type; };

template< typename T >
struct dereference< T* >
{ typedef T type; };
template< typename T >
struct dereference< T* const >
{ typedef T type; };
template< typename T >
struct dereference< T* volatile >
{ typedef T type; };
template< typename T >
struct dereference< T* const volatile >
{ typedef T type; };

template< typename T, std::size_t N >
struct dereference< T[ N ] >
{ typedef T type; };
template< typename T, std::size_t N >
struct dereference< const T[ N ] >
{ typedef T type; };
template< typename T, std::size_t N >
struct dereference< volatile T[ N ] >
{ typedef T type; };
template< typename T, std::size_t N >
struct dereference< const volatile T[ N ] >
{ typedef T type; };

// wrapper

template< typename iterator >
inline void my_for_each( const iterator& t, const iterator& u )
{
   for_each_impl< dereference< iterator >::type >( t, u );
}

// main

int main()
{
   std::vector< int > v;
   std::list< double > l;

   my_for_each( v.begin(), v.end() );
   my_for_each( l.begin(), l.end() );
}

Regards, Daniel

--
Daniel Frey

aixigo AG - financial training, research and technology
Schlo=DF-Rahe-Stra=DFe 15, 52072 Aachen, Germany
fon: +49 (0)241 936737-42, fax: +49 (0)241 936737-99
eMail: daniel.frey@aixigo.de, web: http://www.aixigo.de

---
[ 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                       ]





Author: "Markus Mauhart" <markus.mauhart@nospamm.chello.at>
Date: Tue, 25 Jun 2002 06:53:00 GMT
Raw View
"Daniel Frey" <daniel.frey@aixigo.de> wrote ...

>
>   // v2: With proper support from the STL iterator:
>   // for_each_impl< typename iterator::value_type >( t, u );

Isnt there some template trick to get the hypothetical
"iterator::value_type" out of "iterator::operator *()" ?

> > Your solution:
> > MYCONT::begin()/end() dont return MYCONT::iterator's but some type
> > transparently convertible to MYCONT::iterator; additionally I provide
> > inline versions of the interesing algorithms specialized for the
> > two MYCONT::begin/End/Iterator (dummy-)types which e.g. in the case of
> > "algorithm(MYCONT::beginIterator, MYCONT::endIterator)" ignore the
> > values but call my actual "algorithm(MYCONT,..)" optimized version.
>
> Through derivation, begin_iterator ISA iterator. Sure there might be
> special cases where this might be a problem and I haven't said that I
> have the best solution ever. It's just an idea, another approach to
> consider...

You have choosen derivation for your proxy to avoid most conversion
problems ? Hence I had to add "I provide inline versions" so that the
compiler can optimize away those fat and useless iterators.

> > Really interesting, allthough as you have pointed out maybe some
> > compatibility problems:
> >
> > 23.1, table 65 requires container::iterator as the return type
> > of begin()/end(), and IIRC this is a known problem for any
> > container that wanted to return some proxies from begin/end().
>
> Yes, I am aware of this. The question is, whether a type derived from
> iterator qualifies as an iterator :)

You asked me and here is the answer: yes, but that holds only for the
types and not for objects of that type ;-)

> > Anyway, I'm neither a STL nor a conversion expert, so generally
> > I'd prefer to avoid this trick; maybe I'll use it; and maybe
> > my doku will say "do you a favour, use algorithm(cont,..)
> > instead of algorithm(cont.begin(),cont.end(),..)".
>
> The basic question of this thread deals with a new STL-version, not the
> current one. Thus, I think anything should be discussed which is not too
> far from the current standard and which might improve things.

I dont think that the minimal and IMHO orthogonal addition raised by
the OP needed a new STL version. IMHO it's a good idea to keep in mind.


Markus.





---
[ 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                       ]





Author: Daniel Frey <daniel.frey@aixigo.de>
Date: Tue, 25 Jun 2002 15:21:06 GMT
Raw View
Markus Mauhart wrote:
>=20
> "Daniel Frey" <daniel.frey@aixigo.de> wrote ...
>=20
> >   // v2: With proper support from the STL iterator:
> >   // for_each_impl< typename iterator::value_type >( t, u );
>=20
> Isnt there some template trick to get the hypothetical
> "iterator::value_type" out of "iterator::operator *()" ?

Maybe, but why not just add value_type for 'real' iterators? Shouldn't
break anything AFAICS, not hard to implement and already done for the
GCC's STL. (See my other post)

> > > Your solution:
> > > MYCONT::begin()/end() dont return MYCONT::iterator's but some type
> > > transparently convertible to MYCONT::iterator; additionally I provi=
de
> > > inline versions of the interesing algorithms specialized for the
> > > two MYCONT::begin/End/Iterator (dummy-)types which e.g. in the case=
 of
> > > "algorithm(MYCONT::beginIterator, MYCONT::endIterator)" ignore the
> > > values but call my actual "algorithm(MYCONT,..)" optimized version.
> >
> > Through derivation, begin_iterator ISA iterator. Sure there might be
> > special cases where this might be a problem and I haven't said that I
> > have the best solution ever. It's just an idea, another approach to
> > consider...
>=20
> You have choosen derivation for your proxy to avoid most conversion
> problems ? Hence I had to add "I provide inline versions" so that the
> compiler can optimize away those fat and useless iterators.

My point was that you don't need algorithm(MYCONT,..), as anything (from
the optimization point of view, which I was refering to) can be done
without it (given begin_iterator/end_iterator). Thus,
algorithm(MYCONT,..) lacks the argument of being required to provide
optimized algorithms. Of course, you might find algorithm(MYCONT,..)
more convenient, but that's another point.

> > > Really interesting, allthough as you have pointed out maybe some
> > > compatibility problems:
> > >
> > > 23.1, table 65 requires container::iterator as the return type
> > > of begin()/end(), and IIRC this is a known problem for any
> > > container that wanted to return some proxies from begin/end().
> >
> > Yes, I am aware of this. The question is, whether a type derived from
> > iterator qualifies as an iterator :)
>=20
> You asked me and here is the answer: yes, but that holds only for the
> types and not for objects of that type ;-)

Agreed, but it you write

  iterator it =3D v.begin();

you have an object of type 'iterator', not 'begin_iterator' :))
Honestly, I don't know any code that will break if 'begin()' returns
'begin_iterator' instead of 'iterator', but that doesn't mean that such
code doesn't exist. Changing the existing standard is generally not a
good idea, but playing with ideas is. And for any rule there are
exceptions :)

> > The basic question of this thread deals with a new STL-version, not t=
he
> > current one. Thus, I think anything should be discussed which is not =
too
> > far from the current standard and which might improve things.
>=20
> I dont think that the minimal and IMHO orthogonal addition raised by
> the OP needed a new STL version. IMHO it's a good idea to keep in mind.

Currently, it isn't part of the STL, so we are always talking about a
'new' STL. Both suggestions (the OP's and mine) don't want to reinvent
the wheel, we both want to improve it. Please also note that my ideas
can be separated into two: 1) You can specialize algorithms for a
container type. This means, a lot of the potential optimizations should
already be possible. 2) You can use begin_iterator/end_iterator to
further improve specializing algorithms (and other stuff), but this
might break some code. Is it worth it? IMHO no, but I was just spilling
out ideas to discuss them, I wasn't suggesting to use them ;)

Regards, Daniel

--
Daniel Frey

aixigo AG - financial training, research and technology
Schlo=DF-Rahe-Stra=DFe 15, 52072 Aachen, Germany
fon: +49 (0)241 936737-42, fax: +49 (0)241 936737-99
eMail: daniel.frey@aixigo.de, web: http://www.aixigo.de

---
[ 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                       ]





Author: jpotter@falcon.lhup.edu (John Potter)
Date: Thu, 20 Jun 2002 17:28:57 GMT
Raw View
On Mon, 17 Jun 2002 19:50:37 GMT, "Thorsten Ottosen"
<nesotto@cs.auc.dk> wrote:

>"John Potter"  wrote:

>> Generalization opens a can of worms.

>I would say that we are talking about specialization here. The
>standard for of eg. 'for_each' is more general than the new since
>it can take many different ranges, the new only allows one.

You missed the point.  Generalizing for_each to all algorithms is
the can of worms.  If it is good for for_each, it should be good
for all.  (Obviously wrong since for_each is unlike any other
algorithm in its lack of requirements).

John

---
[ 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                       ]





Author: jpotter@falcon.lhup.edu (John Potter)
Date: Thu, 20 Jun 2002 17:29:42 GMT
Raw View
On Mon, 17 Jun 2002 20:59:25 GMT, "Thorsten Ottosen"
<nesotto@cs.auc.dk> wrote:

>"John Potter" <jpotter@falcon.lhup.edu> wrote in message
>news:3d0b82d7.31450784@news.earthlink.net...

>> On Sat, 15 Jun 2002 16:26:23 GMT, "Thorsten Ottosen" <nesotto@cs.auc.dk>
>> wrote:

>> > template <class Container>
>> > ForwardIterator unique( Container& c ); // removed const jp

>> what does it do?  Does it
>> move things toward the front and leave trash at the end like the
>> algorithm

>That would be natural, wouldn't it? Use the same behavior as much as
>possible, only simplify calling syntax.

Not for me.  I would expect unique(c) to be like c.unique().  The
difference is syntactic.  Given the container, there is no excuse
for doing half of a job.  The difference between unique(c) and
unique(b, e) is semantic.

>>or does it reduce the container to only contain the unique
>> items like std::list<>::unique.

>why should one want to mix the behavior from member functons with
>algorithms? I don't see your point.

STL algorithms take ranges and can't modify containers.  They do not
take containers and I see no reason to think that algorithms which
take containers should do anything like those which do not.

>> What is the use of the returned iterator?

>The same as always, I suppose. Consider an example from SGI STL
>documentation:
>==================
>vector<int>::iterator new_end = unique(V.begin(), V.end());
>// new: vector<int>::iterator new_end = unique( V );
>copy(V.begin(), new_end, ostream_iterator<int>(cout, " "));
>==================

That is one example which leaves the container a piece of trash.
Examples often misuse things to make the desired point.  It seems
more appropriate to write:

   unique_copy(V.begin(), V.end(), ostream_iterator<int>(cout, " "));

It is obviously shorter, uses no needless variables, and is more
efficient.  It also leaves the container in a reasonable condition.

The usual use is:

  V.erase(unique(V.begin(), V.end()), V.end());

I would expect unique(V) to do that.

>> Is it required to be efficient?  For vector and deque, it
>> must copy items which is a waste of time for list and not allowed for
>> multiset and multimap.  What characteristic of Container do you use
>> to overload the implementation?

>The reason I made the post was of course to get a fruitful duscussion, so I
>like any critique :). However, I don't see how a new overload will bring new
>dilemmas into the picture.

I see unique(c) much like swap(x, y), except that I don't see a
default implementation.  Like swap, it should be overloaded for all
standard containers.  Now we have a unique which works.  Vector and
deque can use the real algorithm as above, list can call the member,
set and map can be no-ops, but multiset and multimap will need members
which work like list.  Whether multimap should be based on key_type or
value_type must be decided.

You see saving a few keystrokes, I see a whole new library based on a
totally different concept which saves no code.  It may be easier to
use but seems to lack the (failed?) elegance of the STL.  Every
container would need many algorithms as members.

John

---
[ 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                       ]





Author: Daniel Frey <daniel.frey@aixigo.de>
Date: Thu, 20 Jun 2002 17:30:54 GMT
Raw View
Markus Mauhart wrote:
>=20
> "Michiel Salters" <Michiel.Salters@cmg.nl> wrote ...
> >
> > "Thorsten Ottosen" <nesotto@cs.auc.dk> wrote ...
> > >
> > > I was wondering if the 'for_each' algorithm should not be overloade=
d
> > > to take only two arguments s.t.
> > >   for_each( v, print );
> > > would mean the same as
> > >   for_each( v.begin(), v.end(), print );
> > >
> > > Wouldn't this be nice to have? Maybe one could consider similar ove=
rloads
> > > for other algortims?
> >
> > There's always the option of providing it yourself; the added value o=
f
> > putting this overload in std:: isn't obvious to me.
>=20
> I see one great value: performance. For some containers like trees or
> more or less complicated bitsets or ranges iterators are either extreme=
ly
> slow or very fat (and still slow). Then a container specific specializa=
tion
> of for_each(container const&,function) often (e.g. with small and inlin=
ed
> 'function') will result in (IMHO significantly) less and faster code:

I think this should also be possible with the current version of
for_each. This works, as the iterator is referenced through it's
container. Sure there are problems when you try to make the iterator a
typedef so several containers share the same iterator type, but this is
a STL-implementation-specific problem. I also wondered if the following
idea could be used for your point about specializations for begin/end to
work at compile-time:

#include <iostream>

class container {
public:
   class iterator {};

   class begin_iterator : public iterator {
   public:
      explicit begin_iterator( const iterator& it )
            : iterator( it ) {}
   };

   class end_iterator : public iterator {
   public:
      explicit end_iterator( const iterator& it )
            : iterator( it ) {}
   };

   begin_iterator begin()=20
   {
      return begin_iterator( iterator() );
   }

   end_iterator end()=20
   {
      return end_iterator( iterator() );
   }

   iterator any_iterator()
   {
      return iterator();
   }
};

void for_each( container::iterator itBegin,
               container::iterator itEnd )
{
   std::cout << "any/any" << std::endl;
}

void for_each( container::begin_iterator itBegin,
               container::end_iterator itEnd )
{
   std::cout << "begin/end" << std::endl;
}

void for_each( container::iterator itBegin,
               container::end_iterator itEnd )
{
   std::cout << "any/end" << std::endl;
}

int main()
{
   container c;

   // Uses the specializations
   for_each( c.begin(), c.end() );
   for_each( c.any_iterator(), c.end() );
   for_each( c.begin(), c.any_iterator() );
   for_each( c.any_iterator(), c.any_iterator() );

   // This - at least - works...
   container::iterator itBegin =3D c.begin();
   container::iterator itEnd =3D c.end();
   container::iterator itAny =3D c.any_iterator();

   // ...but doesn't use the specializations
   for_each( itBegin, itEnd );
   for_each( itAny, itEnd );
   for_each( itBegin, itAny );
   for_each( itAny, itAny );
}

Would the standard allow a STL-implementation to use such tricks?

Regards, Daniel

--
Daniel Frey

aixigo AG - financial training, research and technology
Schlo=DF-Rahe-Stra=DFe 15, 52072 Aachen, Germany
fon: +49 (0)241 936737-42, fax: +49 (0)241 936737-99
eMail: daniel.frey@aixigo.de, web: http://www.aixigo.de

---
[ 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                       ]





Author: "Thorsten Ottosen" <nesotto@cs.auc.dk>
Date: Thu, 20 Jun 2002 18:50:51 GMT
Raw View
"Ken Alverson" <Ken@Alverson.com> wrote in message
news:aela36$ci9$1@eeyore.INS.cwru.edu...
> "Thorsten Ottosen" <nesotto@cs.auc.dk> wrote in message
> news:aeap92$d2d$1@sunsite.dk...
> > ==========
> >   for_each( v, print );
> > ==========
> > would mean the same as
> > ==========
> >   for_each( v.begin(), v.end(), print );
> > ==========
> >
> > Wouldn't this be nice to have? Maybe one could consider similar
overloads
> > for other algortims?
>
> I haven't thought this all the way through, but I think you'll have a
> difficult (though possibly not impossible) time differentiating:
>
> transform( inIter1, inIter2, outIter, functor );
>
> and
>
> transform( inCont1, inCont2, outIter, functor );
>
> I'm not sure if the output iterator would become a container argument in
> this case too?
I don't know eitrher. I think I imagined the new transforms like this:

transform(  Cnt, outIter, functor );

and

transform( Cnt, inIter, outIter, functor );

which should remove ambiguity.

Thorsten
nesotto@cs.auc.dk


---
[ 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                       ]





Author: "Thorsten Ottosen" <nesotto@cs.auc.dk>
Date: Thu, 20 Jun 2002 19:14:45 GMT
Raw View
"John Potter" <jpotter@falcon.lhup.edu> wrote in message
news:3d0f1f76.54968@news.earthlink.net...
> On Mon, 17 Jun 2002 20:59:25 GMT, "Thorsten Ottosen"
> <nesotto@cs.auc.dk> wrote:
>
> >"John Potter" <jpotter@falcon.lhup.edu> wrote in message
> >news:3d0b82d7.31450784@news.earthlink.net...
>
> >> On Sat, 15 Jun 2002 16:26:23 GMT, "Thorsten Ottosen"
<nesotto@cs.auc.dk>
> >> wrote:
>
> >> > template <class Container>
> >> > ForwardIterator unique( Container& c ); // removed const jp
>
> >> what does it do?  Does it
> >> move things toward the front and leave trash at the end like the
> >> algorithm
>
> >That would be natural, wouldn't it? Use the same behavior as much as
> >possible, only simplify calling syntax.
>
> Not for me.  I would expect unique(c) to be like c.unique().  The
> difference is syntactic.  Given the container, there is no excuse
> for doing half of a job.  The difference between unique(c) and
> unique(b, e) is semantic.
>
> >>or does it reduce the container to only contain the unique
> >> items like std::list<>::unique.
>
> >why should one want to mix the behavior from member functons with
> >algorithms? I don't see your point.
>
> STL algorithms take ranges and can't modify containers.  They do not
> take containers and I see no reason to think that algorithms which
> take containers should do anything like those which do not.
Agree. The behavior should be as close to normal behavior
for algorithms.

>
> >> What is the use of the returned iterator?
>
> >The same as always, I suppose. Consider an example from SGI STL
> >documentation:
> >==================
> >vector<int>::iterator new_end = unique(V.begin(), V.end());
> >// new: vector<int>::iterator new_end = unique( V );
> >copy(V.begin(), new_end, ostream_iterator<int>(cout, " "));
> >==================
>
> That is one example which leaves the container a piece of trash.
> Examples often misuse things to make the desired point.  It seems
> more appropriate to write:
>
>    unique_copy(V.begin(), V.end(), ostream_iterator<int>(cout, " "));
>
> It is obviously shorter, uses no needless variables, and is more
> efficient.  It also leaves the container in a reasonable condition.
Sometimes it's hard to come up with good examples :) But in the new case
I would like to be able write

unique_copy(V, ostream_iterator<int>(cout, " "));


> The usual use is:
>
>   V.erase(unique(V.begin(), V.end()), V.end());
>
> I would expect unique(V) to do that.

Or maybe we should just be able to say

V.erase(unique(V), V.end());

It should be up to the guys in the standard commitee to evaluate
each case. I'm mostly concerned with getting a shorter, conciser notation.


> I see unique(c) much like swap(x, y), except that I don't see a
> default implementation.  Like swap, it should be overloaded for all
> standard containers.  Now we have a unique which works.  Vector and
> deque can use the real algorithm as above, list can call the member,
> set and map can be no-ops, but multiset and multimap will need members
> which work like list.  Whether multimap should be based on key_type or
> value_type must be decided.
>
> You see saving a few keystrokes,
and more comprehensible code, fewer mistakes, the possibility ti
call algirithms with functions' return values.

>I see a whole new library based on a
> totally different concept which saves no code.  It may be easier to
> use but seems to lack the (failed?) elegance of the STL.
If you don't like the STL, why are you then discussing this?

Thortsten


---
[ 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                       ]





Author: jpotter@falcon.lhup.edu (John Potter)
Date: Fri, 21 Jun 2002 05:08:21 GMT
Raw View
On Thu, 20 Jun 2002 19:14:45 GMT, "Thorsten Ottosen"
<nesotto@cs.auc.dk> wrote:

> "John Potter" <jpotter@falcon.lhup.edu> wrote in message
> news:3d0f1f76.54968@news.earthlink.net...

> >I see a whole new library based on a
> > totally different concept which saves no code.  It may be easier to
> > use but seems to lack the (failed?) elegance of the STL.

> If you don't like the STL, why are you then discussing this?

Sorry, I have not been very clear.  I like the STL.  I respectfully
object to your attempt to destroy it.

The STL is a set of general algorithms which operate on sequences
represented by pairs of iterators.  That is a very elegant concept.
As a marketing gimmic, containers were added to provide a convient
way of generating iterator pairs for the algotithms.  Then the
efficiency problems entered.  Some algorithms could be slightly
better on lists and much better on associatives; so, they were
duplicated as members of those containers.  So much for elegance.

There is another school of thought that the failure happened earlier
when iterators were designed to embody two concepts.  There is work
to split the two concepts fixing that error and producing a more
elegant library.  Binary search would work well on the associatives
as well as the sequences, and other things, for example.

Your proposal is for a container centric library.  That is not the
STL.  It might be a very good library, but it is a conceptual change
from the STL not a minor addition to it.

John

---
[ 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                       ]





Author: "Thorsten Ottosen" <nesotto@cs.auc.dk>
Date: Fri, 21 Jun 2002 16:52:27 GMT
Raw View
"John Potter" <jpotter@falcon.lhup.edu> wrote in message
news:3d12a320.56786390@news.earthlink.net...
> On Thu, 20 Jun 2002 19:14:45 GMT, "Thorsten Ottosen"
> <nesotto@cs.auc.dk> wrote:
>
> > "John Potter" <jpotter@falcon.lhup.edu> wrote in message
> > news:3d0f1f76.54968@news.earthlink.net...
>
> > >I see a whole new library based on a
> > > totally different concept which saves no code.  It may be easier to
> > > use but seems to lack the (failed?) elegance of the STL.
>
> > If you don't like the STL, why are you then discussing this?
>
> Sorry, I have not been very clear.  I like the STL.  I respectfully
> object to your attempt to destroy it.
>
> The STL is a set of general algorithms which operate on sequences
> represented by pairs of iterators.
And it still will, even with the extension I propose. The overloaded
versions just extract the ieterators by themselves so the programmer
don't have to.

> That is a very elegant concept.
Sometime we're not just after "elegant concepts" or
super smart design patterns. Sometimes we're after
convenience too. The standard library did have to
provide operator[]() for a map, but doing so
removes a lot of tedious programming. So could the
new overloads.

> There is another school of thought that the failure happened earlier
> when iterators were designed to embody two concepts.  There is work
> to split the two concepts fixing that error and producing a more
> elegant library.  Binary search would work well on the associatives
> as well as the sequences, and other things, for example.
I still can't see how providing overloads for algorithms
break the elegance of the library. Maybe it's because
I'm probably the least experiencd here at std.c++? Could
more people not give their feedback too?

> Your proposal is for a container centric library.  That is not the
> STL.  It might be a very good library, but it is a conceptual change
> from the STL not a minor addition to it.
I most say that's certainly _not_ how I see it.
 (But of course, if you say that
is what I say, then you now better? :) ). Did you see a headline saying
"make std container centric"?. Overloading is part of the language
and should be used if it can simplify things. And if anybody
would ever wright a piece of code (God forbid) that
somehow contained th   s text

XX.begin(), XX.end()

should he not be able to choose a much shorter version of it? I assume
this line is _heavily_ used. Am I wrong? If not, then why not have a
better notation for it?

 When you
start arguing that you would expect the new overloads to do certain things
that might not be the things I expect, I can simply say it doesn't matter.
The important issue must be that there will be _defined_ a standard
way. Thus our bias is irrelevant. If the standard said every
overload that could extract iterators from containers _always_
meant extracting .begin() and .end(), how could that possible
ruin anything?.

As for the containers, I don't quite understand why they do not provide
similar overloads for inserting all elements of another container.

regards

-Thorsten
nesotto@cs.auc.dk



---
[ 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                       ]





Author: "Thorsten Ottosen" <nesotto@cs.auc.dk>
Date: Mon, 17 Jun 2002 19:50:37 GMT
Raw View
BTW
"John Potter"  wrote:

> Generalization opens a can of worms.
I would say that we are talking about specialization here. The
standard for of eg. 'for_each' is more general than the new since
it can take many different ranges, the new only allows one.

Thorsten
nesotto@cs.auc.dk


---
[ 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                       ]





Author: "Thorsten Ottosen" <nesotto@cs.auc.dk>
Date: Mon, 17 Jun 2002 20:59:25 GMT
Raw View
[I'm posting this one again because the first "disappeared"]
"John Potter" <jpotter@falcon.lhup.edu> wrote in message
news:3d0b82d7.31450784@news.earthlink.net...
> On Sat, 15 Jun 2002 16:26:23 GMT, "Thorsten Ottosen" <nesotto@cs.auc.dk>
> wrote:
>
> Now you have really made a mess which does not help your case at all.
>
> > (2)
> >
> > template <class ForwardIterator>
> >
> > ForwardIterator unique(ForwardIterator first, ForwardIterator last);
>
> We know exactly what this does and it only works with mutable iterators.
> It arranges the sequence with unique items at the beginning and garbage
> at the end.  It returns the beginning of the garbage.
>
> >  (1)
> > /** new */
> >
> > template <class Container>
> >
> > ForwardIterator unique( const Container& c );
>
> This function can't do anything because it has a const reference to the
> container.
OK, so mutating algortithms cannot use const. It is not the real issue here.

>  Assuming that you fix that part, what does it do?  Does it
> move things toward the front and leave trash at the end like the
> algorithm
That would be natural, wouldn't it? Use the same behavior as much as
possible, only simplify
calling syntax.

>or does it reduce the container to only contain the unique
> items like std::list<>::unique.
why should one want to mix the behavior from member functons with
algorithms? I don't see your point.

> What is the use of the returned
> iterator?
The same as always, I suppose. Consider an example from SGI STL
documentation:
==================
vector<int>::iterator new_end = unique(V.begin(), V.end());
// new: vector<int>::iterator new_end = unique( V );
copy(V.begin(), new_end, ostream_iterator<int>(cout, " "));
==================

> Is it required to be efficient?  For vector and deque, it
> must copy items which is a waste of time for list and not allowed for
> multiset and multimap.  What characteristic of Container do you use
> to overload the implementation?
The reason I made the post was of course to get a fruitful duscussion, so I
like
any critique :). However, I don't see how a new overload will bring new
dilemmas
into the picture. If one shouldn't use unique as
========
vector v;
...
unique( v.begin(), v.end() )
========
then one wouldn't use it as
========
unique( v );
========
either. The programmer must as always put  little though into its use, nut
the important
thing is that its the same thought as now, isn't it? Moreover, if the
container cannot deliver
the iterators that the algorithm expects (fx, random access iterators), it
should result
in a compile time error (just as now).

> Generalization opens a can of worms.
or provides better abstraction, better reuse, safer programs.

regards

Thorsten
nesotto@cs.auc.dk



---
[ 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                       ]





Author: "Ken Alverson" <Ken@Alverson.com>
Date: Thu, 20 Jun 2002 17:28:06 GMT
Raw View
"Thorsten Ottosen" <nesotto@cs.auc.dk> wrote in message
news:aeap92$d2d$1@sunsite.dk...
> ==========
>   for_each( v, print );
> ==========
> would mean the same as
> ==========
>   for_each( v.begin(), v.end(), print );
> ==========
>
> Wouldn't this be nice to have? Maybe one could consider similar overloads
> for other algortims?

I haven't thought this all the way through, but I think you'll have a
difficult (though possibly not impossible) time differentiating:

transform( inIter1, inIter2, outIter, functor );

and

transform( inCont1, inCont2, outIter, functor );

I'm not sure if the output iterator would become a container argument in
this case too?  And if so, where would things be inserted?  At the end, I
assume...

Ken


---
[ 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                       ]





Author: "Thorsten Ottosen" <nesotto@cs.auc.dk>
Date: Sat, 15 Jun 2002 16:26:23 GMT
Raw View
"Michiel Salters" <Michiel.Salters@cmg.nl> wrote in message
news:cefd6cde.0206140051.608bb8c7@posting.google.com...
> "Thorsten Ottosen" <nesotto@cs.auc.dk> wrote in message
news:<aeap92$d2d$1@sunsite.dk>...
> > I was wondering if the 'for_each' algorithm should not be overloaded to
take
> > only two arguments s.t.
> >   for_each( v, print );
> > would mean the same as
> >   for_each( v.begin(), v.end(), print );
> >
> > Wouldn't this be nice to have? Maybe one could consider similar
overloads
> > for other algortims?
>
> There's always the option of providing it yourself; the added value of
> putting this overload in std:: isn't obvious to me.
I think its wrong just to let people write it themselves when it could just
as well
be written once and for all. I see two benefits: it will save you 15-16
characters each time
it is used, and it is clearer to read because it is less verbose.

> Other algorithms often have a Predicate version, which overloads only via
> the number of parameters ("only" because the Predicate type is a template
> parameter). Adding another version of the algorithm could interfere with
> this template argument deduction. I don't think it's a very big problem
> though; the easiest resolution is to disallow predicates on the shorthand
> form you propose.
In any case? Take unique, for example,
==========================
 (1)
/** new */

template <class Container>

ForwardIterator unique( const Container& c );

(2)

template <class ForwardIterator>

ForwardIterator unique(ForwardIterator first, ForwardIterator last);

(3)

/** new */

template <class Container, class BinaryPredicate>

ForwardIterator unique( const Container& c, BinaryPredicate binary_pred);

(4)

template <class ForwardIterator, class BinaryPredicate>

ForwardIterator unique(ForwardIterator first, ForwardIterator last,
BinaryPredicate binary_pred);

===================================
I don't see how this can clash since the tow arguments in (2) and (3) are
clearly of different
types. Could you elaborate a bit more on your thoughts?

regards

Thorsten,
nesotto@    cs.auc.dk


---
[ 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                       ]





Author: "Markus Mauhart" <markus.mauhart@nospamm.chello.at>
Date: Sat, 15 Jun 2002 23:17:38 GMT
Raw View
"Michiel Salters" <Michiel.Salters@cmg.nl> wrote ...
>
> "Thorsten Ottosen" <nesotto@cs.auc.dk> wrote ...
> >
> > I was wondering if the 'for_each' algorithm should not be overloaded
> > to take only two arguments s.t.
> >   for_each( v, print );
> > would mean the same as
> >   for_each( v.begin(), v.end(), print );
> >
> > Wouldn't this be nice to have? Maybe one could consider similar overloads
> > for other algortims?
>
> There's always the option of providing it yourself; the added value of
> putting this overload in std:: isn't obvious to me.

I see one great value: performance. For some containers like trees or
more or less complicated bitsets or ranges iterators are either extremely
slow or very fat (and still slow). Then a container specific specialization
of for_each(container const&,function) often (e.g. with small and inlined
'function') will result in (IMHO significantly) less and faster code:

* Less code on the callers side

* Less and faster code produced for for_each<TmyCont,TyourFunc>(..)

* Otherwise (that is: now) cause std::for_each<>(MyContIt,MyContIt,yourFunc)
  is known to be slow for MyContIt, the implementor of MyContainer has
  to provide its own specialization of for_each(it,it,func) anyway.

* To get best performance (again think of small and inlined 'function')
  the specialized for_each<>(MyContIt,MyContIt,fu) might even contain
  a special case to be used when start&end are the container's bounds.

The same applies to find_if(iit,iit,pred), copy(iit,iit,pit) and other
algorithms that could profite from "(container const&,..)" arguments,
and probably their std-provided template could be defined in terms
of for_each(container const& c,function):
  std::copy <TCONT,TOIT> (TCONT const& xc,TOIT xoit)
    {for_each<TCONT> (xc,copyDestPlusPlus<TCONT::value_type,TOIT>(xoit)) ;}

So IMHO the benefits (easier to read code, better performance) would be
worth the necessary efforts (add some std algorithms with container
template & function parameter, AND encourage their usage for whole-set-
-operations).


Markus.



---
[ 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                       ]





Author: jpotter@falcon.lhup.edu (John Potter)
Date: Sun, 16 Jun 2002 05:49:04 GMT
Raw View
On Sat, 15 Jun 2002 16:26:23 GMT, "Thorsten Ottosen" <nesotto@cs.auc.dk>
wrote:

Now you have really made a mess which does not help your case at all.

> (2)
>
> template <class ForwardIterator>
>
> ForwardIterator unique(ForwardIterator first, ForwardIterator last);

We know exactly what this does and it only works with mutable iterators.
It arranges the sequence with unique items at the beginning and garbage
at the end.  It returns the beginning of the garbage.

>  (1)
> /** new */
>
> template <class Container>
>
> ForwardIterator unique( const Container& c );

This function can't do anything because it has a const reference to the
container.  Assuming that you fix that part, what does it do?  Does it
move things toward the front and leave trash at the end like the
algorithm or does it reduce the container to only contain the unique
items like std::list<>::unique.  What is the use of the returned
iterator?  Is it required to be efficient?  For vector and deque, it
must copy items which is a waste of time for list and not allowed for
multiset and multimap.  What characteristic of Container do you use
to overload the implementation?

Generalization opens a can of worms.

John

---
[ 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                       ]





Author: James Kanze <kanze@alex.gabi-soft.de>
Date: Sun, 16 Jun 2002 05:34:19 CST
Raw View
"Thorsten Ottosen" <nesotto@cs.auc.dk> writes:

|>  "Michiel Salters" <Michiel.Salters@cmg.nl> wrote in message
|>  news:cefd6cde.0206140051.608bb8c7@posting.google.com...
|>  > "Thorsten Ottosen" <nesotto@cs.auc.dk> wrote in message
|>  > news:<aeap92$d2d$1@sunsite.dk>...
|>  > > I was wondering if the 'for_each' algorithm should not be
|>  > > overloaded to take only two arguments s.t.
|>  > >   for_each( v, print );
|>  > > would mean the same as
|>  > >   for_each( v.begin(), v.end(), print );

|>  > > Wouldn't this be nice to have? Maybe one could consider
|>  > > similar overloads for other algortims?

|>  > There's always the option of providing it yourself; the added
|>  > value of putting this overload in std:: isn't obvious to me.

|>  I think its wrong just to let people write it themselves when it
|>  could just as well be written once and for all. I see two
|>  benefits: it will save you 15-16 characters each time it is used,
|>  and it is clearer to read because it is less verbose.

The real advantage is that you can use the return value of a function
directly to specify the range.  At present, you need a lot of
gymnastics to do this.

--
James Kanze                                mailto:kanze@gabi-soft.de
Conseils en informatique orient   e objet/
                    Beratung in objektorientierter Datenverarbeitung
Ziegelh   ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(0)69 63198627

---
[ 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                       ]





Author: Alec Ross <alec@arlross.demon.co.uk>
Date: Mon, 17 Jun 2002 18:01:09 GMT
Raw View
In article <aecvhr$do7$1@sunsite.dk>, Thorsten Ottosen
<nesotto@cs.auc.dk> writes
>
>"Alec Ross" <alec@arlross.demon.co.uk> wrote in message
>news:Ry27vEAmScC9Ewcz@arlross.demon.co.uk...
>> You might like to look at C++PL 3e, 18.3.1, (pp 512-513).
>
>I'm aware that we could all trivially implement the stuff, but wouldn't it
>be better to make a standard way of doing things?

OK.  Sorry.  Other things being equal I would prefer to be able to call
the relevant functions with a container argument, as well as in the
currently supplied way with two iterators delimiting the sequence.
(That is, to have the overloads supplied as standard where possible.)
--
Alec Ross

---
[ 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                       ]





Author: "Thorsten Ottosen" <nesotto@cs.auc.dk>
Date: Thu, 13 Jun 2002 18:50:22 GMT
Raw View
I was wondering if the 'for_each' algorithm should not be overloaded to take
only two arguments s.t.
==========
  void print( int );
  ...
  vector<int> v;
  ...
  for_each( v, print );
==========
would mean the same as
==========
  for_each( v.begin(), v.end(), print );
==========

Wouldn't this be nice to have? Maybe one could consider similar overloads
for other algortims?

Thorsten Ottosen,
nesotto@cs.auc.dk





---
[ 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                       ]





Author: Daniel Miller <daniel.miller@tellabs.com>
Date: Thu, 13 Jun 2002 20:57:03 GMT
Raw View
Thorsten Ottosen wrote:

> I was wondering if the 'for_each' algorithm should not be overloaded to take
> only two arguments s.t.
> ==========
>   void print( int );
>   ...
>   vector<int> v;
>   ...
>   for_each( v, print );
> ==========
> would mean the same as
> ==========
>   for_each( v.begin(), v.end(), print );
> ==========
>
> Wouldn't this be nice to have? Maybe one could consider similar overloads
> for other algortims?
>
> Thorsten Ottosen,
> nesotto@cs.auc.dk


   You might want to submit this idea to the developers of SGI STL.  SGI
STL contains post-C++98 evolution of STL which might be submitted for
standardization in C++0x.

   http://www.sgi.com/tech/stl
   http://www.stlport.org

   It is not clear whether such post-C++98 evolution of STL comes under
Boost.org's umbrella or not.

---
[ 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                       ]





Author: Alec Ross <alec@arlross.demon.co.uk>
Date: Fri, 14 Jun 2002 14:15:48 GMT
Raw View
You might like to look at C++PL 3e, 18.3.1, (pp 512-513).

In article <aeap92$d2d$1@sunsite.dk>, Thorsten Ottosen
<nesotto@cs.auc.dk> writes
>I was wondering if the 'for_each' algorithm should not be overloaded to take
>only two arguments s.t.
>==========
>  void print( int );
>  ...
>  vector<int> v;
>  ...
>  for_each( v, print );
>==========
>would mean the same as
>==========
>  for_each( v.begin(), v.end(), print );
>==========
>
>Wouldn't this be nice to have? Maybe one could consider similar overloads
>for other algortims?
>
>Thorsten Ottosen,
>nesotto@cs.auc.dk
>
>
>
>
>
>---
>[ 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                       ]
>

--
Alec Ross

---
[ 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                       ]





Author: Michiel.Salters@cmg.nl (Michiel Salters)
Date: Sat, 15 Jun 2002 06:17:33 GMT
Raw View
"Thorsten Ottosen" <nesotto@cs.auc.dk> wrote in message news:<aeap92$d2d$1@sunsite.dk>...
> I was wondering if the 'for_each' algorithm should not be overloaded to take
> only two arguments s.t.
>   for_each( v, print );
> would mean the same as
>   for_each( v.begin(), v.end(), print );
>
> Wouldn't this be nice to have? Maybe one could consider similar overloads
> for other algortims?

There's always the option of providing it yourself; the added value of
putting this overload in std:: isn't obvious to me.

Other algorithms often have a Predicate version, which overloads only via
the number of parameters ("only" because the Predicate type is a template
parameter). Adding another version of the algorithm could interfere with
this template argument deduction. I don't think it's a very big problem
though; the easiest resolution is to disallow predicates on the shorthand
form you propose.

Regards,
--
Michiel Salters

---
[ 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                       ]





Author: "Thorsten Ottosen" <nesotto@cs.auc.dk>
Date: Sat, 15 Jun 2002 06:19:16 GMT
Raw View
"Alec Ross" <alec@arlross.demon.co.uk> wrote in message
news:Ry27vEAmScC9Ewcz@arlross.demon.co.uk...
> You might like to look at C++PL 3e, 18.3.1, (pp 512-513).

I'm aware that we could all trivially implement the stuff, but wouldn't it
be better to make a standard way of doing things?

-Thorsten,
nesotto@cs.auc.dk


---
[ 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                       ]