Topic: Is this valid code?
Author: kuyper@wizard.net (James Kuyper)
Date: Sun, 10 Aug 2003 18:13:38 +0000 (UTC) Raw View
andys@despammed.com (Andy Sawyer) wrote in message news:<d6fetx03.fsf@evo6.com>...
> In article <8b42afac.0308080659.d070a86@posting.google.com>,
> on Fri, 8 Aug 2003 23:30:15 +0000 (UTC),
> kuyper@wizard.net (James Kuyper) wrote:
>
> > kanze@gabi-soft.fr wrote in message
> > news:<d6652001.0308070111.530703e0@posting.google.com>...
> >> dhruvbird@gmx.net ("Dhruv") wrote in message
> >> news:<pan.2003.08.06.16.42.47.353212@gmx.net>...
> >>
> >> > Just for the record, the place wherefrom I got the idea that end() was
> >> > 1 past the last was none but TC++PL,
> >>
> >> This is the historically traditional way of describing it. STL
> >> iterators try to emulate pointers, to some degree, and the C standard
> >> speaks of a pointer one-past-the-end. The end() iterator acts like a
> >> pointer one-past-the-end in C.
> >
> > The key difference being, of course, that arrays of length 0 are not
> > allowed. If they were, then
> >
> > int array[0];
> > int *array_end = array+sizeof(array);
>
> Ironically enough, this particular expression is only garenteed to give
> the (notionally) right value when either the size is 0 or the array is
> of char/signed char/unsigned char. On many platforms, it will fail if
Sorry; of course what I meant was (sizeof array/sizeof array[0]).
Of course, that expression could itself fail due to division by zero,
for certain arrays, in the unlikely event that arrays of size 0 were
ever actually allowed. This has been a subject of a recent discussion
in comp.std.c. My personal opinion is that if 0-length aggregates were
in fact allowed, we would need an elements() operator to extract the
number of elements in an array, reqardless of whether or not it's
element type had a size of 0.
---
[ 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: andys@despammed.com (Andy Sawyer)
Date: Sun, 10 Aug 2003 21:16:54 +0000 (UTC) Raw View
In article <8b42afac.0308101007.7d262e4c@posting.google.com>,
on Sun, 10 Aug 2003 18:13:38 +0000 (UTC),
kuyper@wizard.net (James Kuyper) wrote:
> andys@despammed.com (Andy Sawyer) wrote in message
> news:<d6fetx03.fsf@evo6.com>...
>> In article <8b42afac.0308080659.d070a86@posting.google.com>,
>> on Fri, 8 Aug 2003 23:30:15 +0000 (UTC),
>> kuyper@wizard.net (James Kuyper) wrote:
>>
>> > The key difference being, of course, that arrays of length 0 are not
>> > allowed. If they were, then
>> >
>> > int array[0];
>> > int *array_end = array+sizeof(array);
>>
>> Ironically enough, this particular expression is only garenteed to give
>> the (notionally) right value when either the size is 0 or the array is
>> of char/signed char/unsigned char. On many platforms, it will fail if
>
> Sorry; of course what I meant was (sizeof array/sizeof array[0]).
I suspected as much ;)
> Of course, that expression could itself fail due to division by zero,
> for certain arrays, in the unlikely event that arrays of size 0 were
> ever actually allowed.
Surely the divison by zero would only occur if sizeof(array[0]) wers
zero? This doesn't happen in C++ (and not, AFAIK, in C), since all
objects (as opposed to sub-objects) have a minimum size of 1.
> My personal opinion is that if 0-length aggregates were in fact
> allowed, we would need an elements() operator to extract the number of
> elements in an array, reqardless of whether or not it's element type
> had a size of 0.
Well, in C++ you can write something like:
template<typename T,
size_t N>
size_t elements( T(&)[N] )
{
return N;
}
int x[10];
int *x_end = x + elements( x );
It's not strictly a compile-time constant (although many compilers will
clearly make the optimisation), so you can't write:
int x[10];
bool b[elements(x)];
but it works fine for the "x_end" idiom. And if we did allow 0-element
arrays, it would continue to work (AFAICS).
Regards,
Andy S
--
"Light thinks it travels faster than anything but it is wrong. No matter
how fast light travels it finds the darkness has always got there first,
and is waiting for it." -- Terry Pratchett, Reaper Man
---
[ 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: kuyper@wizard.net (James Kuyper)
Date: Mon, 11 Aug 2003 16:59:52 +0000 (UTC) Raw View
andys@despammed.com (Andy Sawyer) wrote in message news:<wudls0np.fsf@evo6.com>...
> In article <8b42afac.0308101007.7d262e4c@posting.google.com>,
> on Sun, 10 Aug 2003 18:13:38 +0000 (UTC),
> kuyper@wizard.net (James Kuyper) wrote:
>
> > andys@despammed.com (Andy Sawyer) wrote in message
> > news:<d6fetx03.fsf@evo6.com>...
> >> In article <8b42afac.0308080659.d070a86@posting.google.com>,
> >> on Fri, 8 Aug 2003 23:30:15 +0000 (UTC),
> >> kuyper@wizard.net (James Kuyper) wrote:
> >>
> >> > The key difference being, of course, that arrays of length 0 are not
> >> > allowed. If they were, then
> >> >
> >> > int array[0];
> >> > int *array_end = array+sizeof(array);
> >>
> >> Ironically enough, this particular expression is only garenteed to give
> >> the (notionally) right value when either the size is 0 or the array is
> >> of char/signed char/unsigned char. On many platforms, it will fail if
> >
> > Sorry; of course what I meant was (sizeof array/sizeof array[0]).
>
> I suspected as much ;)
>
> > Of course, that expression could itself fail due to division by zero,
> > for certain arrays, in the unlikely event that arrays of size 0 were
> > ever actually allowed.
>
> Surely the divison by zero would only occur if sizeof(array[0]) wers
> zero? This doesn't happen in C++ (and not, AFAIK, in C), since all
> objects (as opposed to sub-objects) have a minimum size of 1.
If you're going to allow 0-length arrays, there are (at least) two
different options: change the standard to require them to have a size
of 0, or require them to have an implementation-defined size of at
least 1. I think I prefer the first solution, though I'm not sure I
like either one.
> > My personal opinion is that if 0-length aggregates were in fact
> > allowed, we would need an elements() operator to extract the number of
> > elements in an array, reqardless of whether or not it's element type
> > had a size of 0.
>
> Well, in C++ you can write something like:
>
> template<typename T,
> size_t N>
> size_t elements( T(&)[N] )
> {
> return N;
> }
>
> int x[10];
> int *x_end = x + elements( x );
>
> It's not strictly a compile-time constant (although many compilers will
> clearly make the optimisation), so you can't write:
>
> int x[10];
> bool b[elements(x)];
>
> but it works fine for the "x_end" idiom. And if we did allow 0-element
> arrays, it would continue to work (AFAICS).
Agreed. My point was, that if 0-element arrays were allowed, then such
a template should be added as part of the standard library, no matter
which of the two options I described was used. They both would break
the current sizeof() idiom. This template has the additional advantage
that it can only be used on real templates; it will fail noisily if
applied to a pointer.
---
[ 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: jdennett@acm.org (James Dennett)
Date: Tue, 12 Aug 2003 18:41:06 +0000 (UTC) Raw View
James Kuyper wrote:
> andys@despammed.com (Andy Sawyer) wrote in message news:<d6fetx03.fsf@evo6.com>...
>
>>In article <8b42afac.0308080659.d070a86@posting.google.com>,
>> on Fri, 8 Aug 2003 23:30:15 +0000 (UTC),
>> kuyper@wizard.net (James Kuyper) wrote:
>>
>>
>>>kanze@gabi-soft.fr wrote in message
>>>news:<d6652001.0308070111.530703e0@posting.google.com>...
>>>
>>>>dhruvbird@gmx.net ("Dhruv") wrote in message
>>>>news:<pan.2003.08.06.16.42.47.353212@gmx.net>...
>>>>
>>>>
>>>>>Just for the record, the place wherefrom I got the idea that end() was
>>>>>1 past the last was none but TC++PL,
>>>>
>>>>This is the historically traditional way of describing it. STL
>>>>iterators try to emulate pointers, to some degree, and the C standard
>>>>speaks of a pointer one-past-the-end. The end() iterator acts like a
>>>>pointer one-past-the-end in C.
>>>
>>>The key difference being, of course, that arrays of length 0 are not
>>>allowed. If they were, then
>>>
>>>int array[0];
>>>int *array_end = array+sizeof(array);
>>
>>Ironically enough, this particular expression is only garenteed to give
>>the (notionally) right value when either the size is 0 or the array is
>>of char/signed char/unsigned char. On many platforms, it will fail if
>
>
> Sorry; of course what I meant was (sizeof array/sizeof array[0]).
>
> Of course, that expression could itself fail due to division by zero,
> for certain arrays, in the unlikely event that arrays of size 0 were
> ever actually allowed. This has been a subject of a recent discussion
> in comp.std.c. My personal opinion is that if 0-length aggregates were
> in fact allowed, we would need an elements() operator to extract the
> number of elements in an array, reqardless of whether or not it's
> element type had a size of 0.
Standard C++ has something to offer if an extension to C
is needed in this area:
template <typename ElementType, std::size_t Size>
std::size_t array_size(ElementType (&)[Size])
{
return Size;
}
;)
More seriously, if C did introduce an extension, it would
be nice if it used syntax that can be implemented as a library
feature in C++.
-- James.
---
[ 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: rridge@csclub.uwaterloo.ca (Ross Ridge)
Date: Wed, 6 Aug 2003 15:02:25 +0000 (UTC) Raw View
<dhruvbird@gmx.net> writes
>2. container.end() returns 1 past the last element.
Francis Glassborow <francis@robinton.demon.co.uk> wrote:
>I think that is an understandable but slightly inaccurate view. .end()
>is required to return an iterator that somehow identifies that you have
>finished. In the case of vectors this would be equivalent to the array's
>one past the last element However in the case of a list, map etc. there
>is no such thing just a special iterator that is valid but cannot be
>dereferenced.
rridge@csclub.uwaterloo.ca (Ross Ridge) wrote:
> It's just as true if the container is a list, map, or whatever. If "i"
> is an iterator that refers to the last element in the container "a",
> then "++i == a.end()" is true no matter what kind of container "a" is.
> The problem with Dhruv's "view" is that it's meaningless when the
> container is empty and there is no last element, and so doesn't help
> him understand the case he has a problem with.
Terje Sletteb <"terjes."@chello.no> wrote:
> The point is....
No, the point is that Dhruv had a misunderstanding, and I explained
exactly what that misunderstanding was. As it turned out this was
the relevation Dhruv needed to come to a correct understanding of his
problem case. Case closed. Days ago.
Ross Ridge
--
l/ // Ross Ridge -- The Great HTMU
[oo][oo] rridge@csclub.uwaterloo.ca
-()-/()/ http://www.csclub.uwaterloo.ca/u/rridge/
db //
---
[ 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: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Wed, 6 Aug 2003 15:02:41 +0000 (UTC) Raw View
In article <d6fodoki.fsf@evo6.com>, Andy Sawyer <andys@despammed.com>
writes
> if( c.begin() != c.end() ) { /* do stuff */ }
>
> if( c.size() ) { /* do stuff */ }
>
> if( c.size() != 0 } { /* do stuff */ }
>
> if( !c.empty() ) { /* do stuff */ }
>
>
>Again, only one of them says exactly what the test is for. And again, it
>would be a poor implementaiton where !c.empty() were any less efficient
>than any of the others.
True, yet only the first generalises to the case where we are defining
our area of interest by using two iterators:
void foo(vector::iterator start, vector::iterator finish){
if(start != finish){ /*do stuff */}
the remaining versions only apply to whole containers. Once the
programmer is familiar with the idiom, there is no great advantage in
using .empty() for the special case.
--
Francis Glassborow ACCU
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ 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: dhruvbird@gmx.net ("Dhruv")
Date: Wed, 6 Aug 2003 16:47:00 +0000 (UTC) Raw View
On Wed, 06 Aug 2003 15:02:25 +0000, Ross Ridge wrote:
> <dhruvbird@gmx.net> writes
>>2. container.end() returns 1 past the last element.
>=20
> Francis Glassborow <francis@robinton.demon.co.uk> wrote:
>>I think that is an understandable but slightly inaccurate view. .end()=20
>>is required to return an iterator that somehow identifies that you have=
=20
>>finished. In the case of vectors this would be equivalent to the array'=
s=20
>>one past the last element However in the case of a list, map etc. there=
=20
>>is no such thing just a special iterator that is valid but cannot be=20
>>dereferenced.
> =20
> rridge@csclub.uwaterloo.ca (Ross Ridge) wrote:
>> It's just as true if the container is a list, map, or whatever. If "i=
"
>> is an iterator that refers to the last element in the container "a",
>> then "++i =3D=3D a.end()" is true no matter what kind of container "a"=
is.
>> The problem with Dhruv's "view" is that it's meaningless when the
>> container is empty and there is no last element, and so doesn't help
>> him understand the case he has a problem with.
>=20
> Terje Sletteb=F8 <"terjes."@chello.no> wrote:
>> The point is....
>=20
> No, the point is that Dhruv had a misunderstanding, and I explained
> exactly what that misunderstanding was. As it turned out this was
> the relevation Dhruv needed to come to a correct understanding of his
> problem case. Case closed. Days ago.
Just for the record, the place wherefrom I got the idea that end() was 1
past the last was none but TC++PL, (special edition) page-462, table
16.3.2 (Iterators). I think Ross put the dilema in a very good way, sayin=
g
that if i is an iterator..., then ++i =3D=3D end(), and stuff...... I was
having problems fitting that definition here, but now, all of that is
cleared up due to the new definition of end() as indicating the end of th=
e
sequence.
Regards,
-Dhruv.
---
[ 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: andys@despammed.com (Andy Sawyer)
Date: Thu, 7 Aug 2003 02:50:02 +0000 (UTC) Raw View
In article <+JfqmBFvmMM$EwjD@robinton.demon.co.uk>,
on Wed, 6 Aug 2003 15:02:41 +0000 (UTC),
francis@robinton.demon.co.uk (Francis Glassborow) wrote:
> In article <d6fodoki.fsf@evo6.com>, Andy Sawyer <andys@despammed.com>
> writes
>> if( c.begin() != c.end() ) { /* do stuff */ }
>>
>> if( c.size() ) { /* do stuff */ }
>>
>> if( c.size() != 0 } { /* do stuff */ }
>>
>> if( !c.empty() ) { /* do stuff */ }
>>
>>
>>Again, only one of them says exactly what the test is for. And again, it
>>would be a poor implementaiton where !c.empty() were any less efficient
>>than any of the others.
>
> True, yet only the first generalises to the case where we are defining
> our area of interest by using two iterators:
Only the first generalises to a case we weren't discussing, yes.
> the remaining versions only apply to whole containers. Once the
> programmer is familiar with the idiom, there is no great advantage in
> using .empty() for the special case.
Apart from potential (and potentially considerable) performance
gains. Sometimes, every clock cycle really does count (not all software
runs on multi-GHz - or even single-GHz - processors). Sometimes they
count for other reasons (battery life being a common example).
Regards,
Andy S.
--
"Light thinks it travels faster than anything but it is wrong. No matter
how fast light travels it finds the darkness has always got there first,
and is waiting for it." -- Terry Pratchett, Reaper Man
---
[ 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: kanze@gabi-soft.fr
Date: Thu, 7 Aug 2003 14:23:48 +0000 (UTC) Raw View
dhruvbird@gmx.net ("Dhruv") wrote in message
news:<pan.2003.08.06.16.42.47.353212@gmx.net>...
> Just for the record, the place wherefrom I got the idea that end() was
> 1 past the last was none but TC++PL,
This is the historically traditional way of describing it. STL
iterators try to emulate pointers, to some degree, and the C standard
speaks of a pointer one-past-the-end. The end() iterator acts like a
pointer one-past-the-end in C.
In practice, the emulation is only partial, and the formulation of
one-past-the-end is probably only intuitive to those who have worked in
C, and are familiar with the C standard.
--
James Kanze GABI Software mailto:kanze@gabi-soft.fr
Conseils en informatique orient e objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16
---
[ 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: andys@despammed.com (Andy Sawyer)
Date: Fri, 8 Aug 2003 05:01:36 +0000 (UTC) Raw View
In article <pan.2003.08.06.16.42.47.353212@gmx.net>,
on Wed, 6 Aug 2003 16:47:00 +0000 (UTC),
dhruvbird@gmx.net ("Dhruv") wrote:
> Just for the record, the place wherefrom I got the idea that end() was 1
> past the last was none but TC++PL, (special edition) page-462, table
> 16.3.2 (Iterators).
The Standard includes the term "past-the-end" (24.1/5):
,----
| Just as a regular pointer to an array guarantees that there is a
| pointer value pointing past the last element of the array, so for any
| iterator type there is an iterator value that points past the last
| element of a corresponding container. These values are called
| *past-the-end* values.
`----
- although it doesn't specify *1* past-the-end :)
Regards,
Andy S
--
"Light thinks it travels faster than anything but it is wrong. No matter
how fast light travels it finds the darkness has always got there first,
and is waiting for it." -- Terry Pratchett, Reaper Man
---
[ 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: kuyper@wizard.net (James Kuyper)
Date: Fri, 8 Aug 2003 23:30:15 +0000 (UTC) Raw View
kanze@gabi-soft.fr wrote in message news:<d6652001.0308070111.530703e0@posting.google.com>...
> dhruvbird@gmx.net ("Dhruv") wrote in message
> news:<pan.2003.08.06.16.42.47.353212@gmx.net>...
>
> > Just for the record, the place wherefrom I got the idea that end() was
> > 1 past the last was none but TC++PL,
>
> This is the historically traditional way of describing it. STL
> iterators try to emulate pointers, to some degree, and the C standard
> speaks of a pointer one-past-the-end. The end() iterator acts like a
> pointer one-past-the-end in C.
The key difference being, of course, that arrays of length 0 are not
allowed. If they were, then
int array[0];
int *array_end = array+sizeof(array);
would be exactly analogous to:
std::vector<int> array;
std::vector<int>::iterator array_end = array.end();
A more direct analogy to the C++ code that is actually legal would be:
int array[MAX_ELEMENTS];
size_t n_elements=0;
int *array_end = array+n_elements;
---
[ 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: andys@despammed.com (Andy Sawyer)
Date: Sat, 9 Aug 2003 20:10:23 +0000 (UTC) Raw View
In article <8b42afac.0308080659.d070a86@posting.google.com>,
on Fri, 8 Aug 2003 23:30:15 +0000 (UTC),
kuyper@wizard.net (James Kuyper) wrote:
> kanze@gabi-soft.fr wrote in message
> news:<d6652001.0308070111.530703e0@posting.google.com>...
>> dhruvbird@gmx.net ("Dhruv") wrote in message
>> news:<pan.2003.08.06.16.42.47.353212@gmx.net>...
>>
>> > Just for the record, the place wherefrom I got the idea that end() was
>> > 1 past the last was none but TC++PL,
>>
>> This is the historically traditional way of describing it. STL
>> iterators try to emulate pointers, to some degree, and the C standard
>> speaks of a pointer one-past-the-end. The end() iterator acts like a
>> pointer one-past-the-end in C.
>
> The key difference being, of course, that arrays of length 0 are not
> allowed. If they were, then
>
> int array[0];
> int *array_end = array+sizeof(array);
Ironically enough, this particular expression is only garenteed to give
the (notionally) right value when either the size is 0 or the array is
of char/signed char/unsigned char. On many platforms, it will fail if
you declare:
int array[1];
int *array_end = array+sizeof(array);
Regards,
Andy S
--
"Light thinks it travels faster than anything but it is wrong. No matter
how fast light travels it finds the darkness has always got there first,
and is waiting for it." -- Terry Pratchett, Reaper Man
---
[ 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: dhruvbird@gmx.net ("Dhruv")
Date: Tue, 29 Jul 2003 19:36:42 +0000 (UTC) Raw View
On Tue, 29 Jul 2003 18:39:07 +0000, Andrew Koenig wrote:
> Dhruv> I wanted to know if this is considered valid C++?
>
> Dhruv> std::vector<int> v;
> Dhruv> v.insert (v.begin(), 1);
>
> I don't see anything wrong with it. What do you think is the problem?
Technically, you can in code protect against v.begin() being 0 or
something, but speaking generally, I could argue that there is nothing in
v, how can v.begin() point to a valid iterator (iterator => gereralization
of a pointer to an element in a container).
Regards,
-Dhruv.
---
[ 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: v.Abazarov@attAbi.com ("Victor Bazarov")
Date: Tue, 29 Jul 2003 20:57:42 +0000 (UTC) Raw View
"Dhruv" <dhruvbird@gmx.net> wrote...
> On Tue, 29 Jul 2003 18:39:07 +0000, Andrew Koenig wrote:
>
> > Dhruv> I wanted to know if this is considered valid C++?
> >
> > Dhruv> std::vector<int> v;
> > Dhruv> v.insert (v.begin(), 1);
> >
> > I don't see anything wrong with it. What do you think is the problem?
>
> Technically, you can in code protect against v.begin() being 0 or
> something, but speaking generally, I could argue that there is nothing in
> v, how can v.begin() point to a valid iterator (iterator => gereralization
> of a pointer to an element in a container).
If 'v' is empty, 'v.begin()' will return (not "point to") the same
iterator as 'v.end()', which is a valid iterator that corresponds
to "one element past the last one". The same way as the pointer
obtained by adding the size of the array to the pointer of the
first element of the array is a valid pointer:
int a[100];
int* pa = a + 100; // 'pa' is a valid pointer, although you
// cannot dereference it.
Victor
---
[ 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: sebmol@yahoo.com ("Sebastian Moleski")
Date: Wed, 30 Jul 2003 01:05:25 +0000 (UTC) Raw View
""Dhruv"" <dhruvbird@gmx.net> wrote in message
news:pan.2003.07.29.09.24.02.401578@gmx.net...
> I wanted to know if this is considered valid C++?
> I guess it should be UB, but could not find anything to that effect in the
> standard document.
>
> std::vector<int> v;
> v.insert (v.begin(), 1);
One of vector's insert overloads takes an iterator and a value, which is what
you are doing here. So, yes, the code is valid.
sm
---
[ 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: andys@despammed.com (Andy Sawyer)
Date: Wed, 30 Jul 2003 01:08:54 +0000 (UTC) Raw View
In article <pan.2003.07.29.19.44.53.357695@gmx.net>,
on Tue, 29 Jul 2003 19:36:42 +0000 (UTC),
dhruvbird@gmx.net ("Dhruv") wrote:
> On Tue, 29 Jul 2003 18:39:07 +0000, Andrew Koenig wrote:
>
>> Dhruv> I wanted to know if this is considered valid C++?
>>
>> Dhruv> std::vector<int> v;
>> Dhruv> v.insert (v.begin(), 1);
>>
>> I don't see anything wrong with it. What do you think is the problem?
>
> Technically, you can in code protect against v.begin() being 0 or
> something, but speaking generally, I could argue that there is nothing in
> v, how can v.begin() point to a valid iterator (iterator => gereralization
> of a pointer to an element in a container).
>
v.begin() is a _valid_ iterator, but it's not a _dereferenceable_
iterator (just like v.end() in the more general case). Iterators don't
have to be dereferencable to be valid.
Regards,
Andy S
--
"Light thinks it travels faster than anything but it is wrong. No matter
how fast light travels it finds the darkness has always got there first,
and is waiting for it." -- Terry Pratchett, Reaper Man
---
[ 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: kuyper@wizard.net (James Kuyper)
Date: Wed, 30 Jul 2003 14:25:47 +0000 (UTC) Raw View
dhruvbird@gmx.net ("Dhruv") wrote in message news:<pan.2003.07.29.09.24.02.401578@gmx.net>...
> I wanted to know if this is considered valid C++?
> I guess it should be UB, but could not find anything to that effect in the
> standard document.
>
> std::vector<int> v;
> v.insert (v.begin(), 1);
Other people have told you that this is legal, but I think you should
also understand why it's legal. You've created an empty vector; this
is something the standard allows. The only purpose of an empty vector
is that it can be filled in. If it weren't legal to insert a first
element into an empty vector, what would be the point of allowing one
to be created?
You could use the push_front() and push_back() member functions to
insert that first member, but that doesn't help: the push functions
are defined in terms of insert(), begin(), and end(), so if the insert
you were asking about had UB, then so would v.push_front(1).
---
[ 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: v.Abazarov@attAbi.com ("Victor Bazarov")
Date: Wed, 30 Jul 2003 23:47:36 +0000 (UTC) Raw View
"Dhruv" <dhruvbird@gmx.net> wrote...
> I wanted to know if this is considered valid C++?
> I guess it should be UB, but could not find anything to that effect in the
> standard document.
>
> std::vector<int> v;
> v.insert (v.begin(), 1);
It's valid. The behaviour is the same as
std::vector<int> v;
v.push_back(1);
See table 68. For an empty vector v.begin() returns the same
value as v.end(). And v.insert(v.end(), 1) for an any vector
is the same as v.push_back(1).
Victor
---
[ 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.net (Ken Alverson)
Date: Wed, 30 Jul 2003 23:47:44 +0000 (UTC) Raw View
"Andrew Koenig" <ark@acm.org> wrote in message
news:yu99d6ft6vf3.fsf@tinker.research.att.com...
> Dhruv> I wanted to know if this is considered valid C++?
>
> Dhruv> std::vector<int> v;
> Dhruv> v.insert (v.begin(), 1);
>
> I don't see anything wrong with it. What do you think is the problem?
I'm guessing he was either worried about
a) insert invalidating the begin() iterator or
b) begin() being end(), which points at a location outside the vector
Point A is ok, because the iterator only has to be valid a the time insert is
called, point B is ok because insert places the element before the given
iterator, so end() is a valid location to insert.
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: dhruvbird@gmx.net ("Dhruv")
Date: Wed, 30 Jul 2003 23:47:57 +0000 (UTC) Raw View
On Tue, 29 Jul 2003 20:57:42 +0000, Victor Bazarov wrote:
> "Dhruv" <dhruvbird@gmx.net> wrote...
>> On Tue, 29 Jul 2003 18:39:07 +0000, Andrew Koenig wrote:
>>
>> > Dhruv> I wanted to know if this is considered valid C++?
>> >
>> > Dhruv> std::vector<int> v;
>> > Dhruv> v.insert (v.begin(), 1);
>> >
>> > I don't see anything wrong with it. What do you think is the problem?
>>
>> Technically, you can in code protect against v.begin() being 0 or
>> something, but speaking generally, I could argue that there is nothing in
>> v, how can v.begin() point to a valid iterator (iterator => gereralization
>> of a pointer to an element in a container).
>
> If 'v' is empty, 'v.begin()' will return (not "point to") the same
> iterator as 'v.end()', which is a valid iterator that corresponds
> to "one element past the last one". The same way as the pointer
> obtained by adding the size of the array to the pointer of the
> first element of the array is a valid pointer:
>
int main ()
{
std::vector<int> v;
assert (v.begin() != v.end ());
}
The assertion fails on my implimentation.
> int a[100];
> int* pa = a + 100; // 'pa' is a valid pointer, although you
> // cannot dereference it.
>
Regards,
-Dhruv.
---
[ 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: v.Abazarov@attAbi.com ("Victor Bazarov")
Date: Thu, 31 Jul 2003 00:37:56 +0000 (UTC) Raw View
"Dhruv" <dhruvbird@gmx.net> wrote...
> [...]
> int main ()
> {
> std::vector<int> v;
> assert (v.begin() != v.end ());
> }
>
> The assertion fails on my implimentation.
As it should. v.begin() == v.end() for an empty vector.
Victor
---
[ 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: dhruvbird@gmx.net ("Dhruv")
Date: Thu, 31 Jul 2003 03:14:40 +0000 (UTC) Raw View
On Wed, 30 Jul 2003 14:25:47 +0000, James Kuyper wrote:
> dhruvbird@gmx.net ("Dhruv") wrote in message news:<pan.2003.07.29.09.24.02.401578@gmx.net>...
>> I wanted to know if this is considered valid C++?
>> I guess it should be UB, but could not find anything to that effect in the
>> standard document.
>>
>> std::vector<int> v;
>> v.insert (v.begin(), 1);
>
> Other people have told you that this is legal, but I think you should
> also understand why it's legal. You've created an empty vector; this
> is something the standard allows. The only purpose of an empty vector
> is that it can be filled in. If it weren't legal to insert a first
> element into an empty vector, what would be the point of allowing one
> to be created?
>
> You could use the push_front() and push_back() member functions to
> insert that first member, but that doesn't help: the push functions
> are defined in terms of insert(), begin(), and end(), so if the insert
> you were asking about had UB, then so would v.push_front(1).
>
I'm having a hard time convincing myself that this is correct, even though
everyone is saying so, and even that now I do feel so, but, I don't know,
it's one of those things that I just keep pondering on, and don't reach a
conclusion.
Here are some of the notions that I have deveveloped over time. They may
not be correct though: I want reasons as to where I'm going wrong.
1. What I have in mind when I write container.begin () is that I should get
an iterator to the first element in that container. If the container is
empty, I don't know what begin() will return.
2. container.end() returns 1 past the last element. If the container is
empty even, begin () == end () should not hold true, eben though I know it
does. I don't know why, but that's how my mind works?????? Then, again
when I think that if the container is empty, then if I iterate using
for_each, or something, this sort of scheme where begin() never equals
end() will always show the container having a single element.
3. push_back() inserts an element at the end of the sequence. If there is
none, it creates one, and the elemnt becomes the head. Same for
push_front().
4. I guess this is cheap, but in places I do use begin()==end() as a test
for whether the container is empty. I should be using empty()......
Help the confused soul :-(
-Dhruv.
---
[ 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: andys@despammed.com (Andy Sawyer)
Date: Thu, 31 Jul 2003 03:18:27 +0000 (UTC) Raw View
In article <8b42afac.0307300522.3aaafaf3@posting.google.com>,
on Wed, 30 Jul 2003 14:25:47 +0000 (UTC),
kuyper@wizard.net (James Kuyper) wrote:
> The only purpose of an empty vector is that it can be filled in. If it
> weren't legal to insert a first element into an empty vector, what
> would be the point of allowing one to be created?
>
> You could use the push_front() and push_back() member functions to
> insert that first member
You'll have a hard time trying to use push_front to populate a vector -
it doesn't have one.
> the push functions are defined in terms of insert(), begin(), and
> end(),
Their behaviour is defined in terms of the behaviour of insert and so on
- that doesn't mean the functions themselves are necessarily defined
that way.
Regards,
Andy S
--
"Light thinks it travels faster than anything but it is wrong. No matter
how fast light travels it finds the darkness has always got there first,
and is waiting for it." -- Terry Pratchett, Reaper Man
---
[ 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: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Thu, 31 Jul 2003 18:01:16 +0000 (UTC) Raw View
In article <pan.2003.07.30.16.15.05.594559@gmx.net>, Dhruv
<dhruvbird@gmx.net> writes
>1. What I have in mind when I write container.begin () is that I should get
>an iterator to the first element in that container. If the container is
>empty, I don't know what begin() will return.
An iterator that is required to be the same as that returned by end().
>
>2. container.end() returns 1 past the last element.
I think that is an understandable but slightly inaccurate view. .end()
is required to return an iterator that somehow identifies that you have
finished. In the case of vectors this would be equivalent to the array's
one past the last element However in the case of a list, map etc. there
is no such thing just a special iterator that is valid but cannot be
dereferenced.
> If the container is
>empty even, begin () == end () should not hold true,
Except that the rule makers specified that it will be true, indeed the
point is that it generalises to subcontainers. Any time the start
iterator == the finish iterator you have an empty collection.
>eben though I know it
>does. I don't know why, but that's how my mind works?????? Then, again
>when I think that if the container is empty, then if I iterate using
>for_each, or something, this sort of scheme where begin() never equals
>end() will always show the container having a single element.
Exactly, which is why the rule was written the way it was. You will have
to retrain your intuition.
--
Francis Glassborow ACCU
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ 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: kuyper@wizard.net (James Kuyper)
Date: Thu, 31 Jul 2003 18:01:30 +0000 (UTC) Raw View
andys@despammed.com (Andy Sawyer) wrote in message news:<65ljn1fd.fsf@evo6.com>...
> In article <8b42afac.0307300522.3aaafaf3@posting.google.com>,
> on Wed, 30 Jul 2003 14:25:47 +0000 (UTC),
> kuyper@wizard.net (James Kuyper) wrote:
>
> > The only purpose of an empty vector is that it can be filled in. If it
> > weren't legal to insert a first element into an empty vector, what
> > would be the point of allowing one to be created?
> >
> > You could use the push_front() and push_back() member functions to
> > insert that first member
>
> You'll have a hard time trying to use push_front to populate a vector -
> it doesn't have one.
True. I should have restricted my comments to push_back().
> > the push functions are defined in terms of insert(), begin(), and
> > end(),
>
> Their behaviour is defined in terms of the behaviour of insert and so on
> - that doesn't mean the functions themselves are necessarily defined
> that way.
True, they can be defined in any way that produces the same observable
behavior under any circumstance where that behavior is defined. My
point was that if Dhruv's reason for thinking that insert(begin(),1)
should have undefined behavior were valid, then they would probably
also apply equally well to insert(end(),1). Since push_back(t) is
defined as insert(end(),t), if he were right, then push_back(t) would
also have undefined behavior on empty vectors.
---
[ 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: rridge@csclub.uwaterloo.ca (Ross Ridge)
Date: Thu, 31 Jul 2003 21:47:41 +0000 (UTC) Raw View
<dhruvbird@gmx.net> writes
>2. container.end() returns 1 past the last element.
Francis Glassborow <francis@robinton.demon.co.uk> wrote:
>I think that is an understandable but slightly inaccurate view. .end()
>is required to return an iterator that somehow identifies that you have
>finished. In the case of vectors this would be equivalent to the array's
>one past the last element However in the case of a list, map etc. there
>is no such thing just a special iterator that is valid but cannot be
>dereferenced.
It's just as true if the container is a list, map, or whatever. If "i"
is an iterator that refers to the last element in the container "a",
then "++i == a.end()" is true no matter what kind of container "a" is.
The problem with Dhruv's "view" is that it's meaningless when the
container is empty and there is no last element, and so doesn't help
him understand the case he has a problem with.
Ross Ridge
--
l/ // Ross Ridge -- The Great HTMU
[oo][oo] rridge@csclub.uwaterloo.ca
-()-/()/ http://www.csclub.uwaterloo.ca/u/rridge/
db //
---
[ 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: kuyper@wizard.net (James Kuyper)
Date: Fri, 1 Aug 2003 05:46:51 +0000 (UTC) Raw View
dhruvbird@gmx.net ("Dhruv") wrote in message news:<pan.2003.07.30.16.15.05.594559@gmx.net>...
> On Wed, 30 Jul 2003 14:25:47 +0000, James Kuyper wrote:
>
> > dhruvbird@gmx.net ("Dhruv") wrote in message news:<pan.2003.07.29.09.24.02.401578@gmx.net>...
> >> I wanted to know if this is considered valid C++?
> >> I guess it should be UB, but could not find anything to that effect in the
> >> standard document.
> >>
> >> std::vector<int> v;
> >> v.insert (v.begin(), 1);
> >
> > Other people have told you that this is legal, but I think you should
> > also understand why it's legal. You've created an empty vector; this
> > is something the standard allows. The only purpose of an empty vector
> > is that it can be filled in. If it weren't legal to insert a first
> > element into an empty vector, what would be the point of allowing one
> > to be created?
> >
> > You could use the push_front() and push_back() member functions to
> > insert that first member, but that doesn't help: the push functions
> > are defined in terms of insert(), begin(), and end(), so if the insert
> > you were asking about had UB, then so would v.push_front(1).
> >
>
> I'm having a hard time convincing myself that this is correct, even though
> everyone is saying so, and even that now I do feel so, but, I don't know,
> it's one of those things that I just keep pondering on, and don't reach a
> conclusion.
>
> Here are some of the notions that I have deveveloped over time. They may
> not be correct though: I want reasons as to where I'm going wrong.
>
> 1. What I have in mind when I write container.begin () is that I should get
> an iterator to the first element in that container. If the container is
> empty, I don't know what begin() will return.
If your container has some space already reserved for what would be
the first element after a push_front(), then return an iterator that
points to that element. Otherwise, return an iterator that points at
something, anything, so long as it points at the same thing as end().
> 2. container.end() returns 1 past the last element. If the container is
> empty even, begin () == end () should not hold true
Why not? Consider the following:
2 element vector: end()==begin()+2
1 element vector: end()==begin()+1
0 element vector: end()==begin()+0==begin()
It's a simple matter of continuity.
---
[ 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: dhruvbird@gmx.net ("Dhruv")
Date: Fri, 1 Aug 2003 07:06:10 +0000 (UTC) Raw View
On Thu, 31 Jul 2003 18:01:16 +0000, Francis Glassborow wrote:
> In article <pan.2003.07.30.16.15.05.594559@gmx.net>, Dhruv
> <dhruvbird@gmx.net> writes
>>1. What I have in mind when I write container.begin () is that I should get
>>an iterator to the first element in that container. If the container is
>>empty, I don't know what begin() will return.
>
> An iterator that is required to be the same as that returned by end().
>>
>>2. container.end() returns 1 past the last element.
>
> I think that is an understandable but slightly inaccurate view. .end()
> is required to return an iterator that somehow identifies that you have
> finished. In the case of vectors this would be equivalent to the array's
> one past the last element However in the case of a list, map etc. there
> is no such thing just a special iterator that is valid but cannot be
> dereferenced.
>
Ok, yes. I guess looking at it this way helps me clear out some of the
glitch that I have in my mind. So, in general, if end() denotes that the
end of the sequence is reached, then the definition of 1 past the last is
not required.
>> If the container is
>>empty even, begin () == end () should not hold true,
> Except that the rule makers specified that it will be true, indeed the
> point is that it generalises to subcontainers. Any time the start
> iterator == the finish iterator you have an empty collection.
>
>>eben though I know it
>>does. I don't know why, but that's how my mind works?????? Then, again
>>when I think that if the container is empty, then if I iterate using
>>for_each, or something, this sort of scheme where begin() never equals
>>end() will always show the container having a single element.
>
> Exactly, which is why the rule was written the way it was. You will have
> to retrain your intuition.
Yes, I do think so myself :-)
Regards,
-Dhruv.
---
[ 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: dhruvbird@gmx.net ("Dhruv")
Date: Fri, 1 Aug 2003 07:06:20 +0000 (UTC) Raw View
On Thu, 31 Jul 2003 21:47:41 +0000, Ross Ridge wrote:
> It's just as true if the container is a list, map, or whatever. If "i"
> is an iterator that refers to the last element in the container "a",
> then "++i == a.end()" is true no matter what kind of container "a" is.
> The problem with Dhruv's "view" is that it's meaningless when the
> container is empty and there is no last element, and so doesn't help
> him understand the case he has a problem with.
Yes, that was precisely the problem. Now that Francis Glassborow has
mentioned the new way of looking at end() as the indicaion that the
sequence is over, everything fits well into place.
Regards,
-Dhruv.
---
[ 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: jdennett@acm.org (James Dennett)
Date: Fri, 1 Aug 2003 22:30:12 +0000 (UTC) Raw View
Dhruv wrote:
> On Tue, 29 Jul 2003 20:57:42 +0000, Victor Bazarov wrote:
>
>
>>"Dhruv" <dhruvbird@gmx.net> wrote...
>>
>>>On Tue, 29 Jul 2003 18:39:07 +0000, Andrew Koenig wrote:
>>>
>>>
>>>>Dhruv> I wanted to know if this is considered valid C++?
>>>>
>>>>Dhruv> std::vector<int> v;
>>>>Dhruv> v.insert (v.begin(), 1);
>>>>
>>>>I don't see anything wrong with it. What do you think is the problem?
>>>
>>>Technically, you can in code protect against v.begin() being 0 or
>>>something, but speaking generally, I could argue that there is nothing in
>>>v, how can v.begin() point to a valid iterator (iterator => gereralization
>>>of a pointer to an element in a container).
>>
>>If 'v' is empty, 'v.begin()' will return (not "point to") the same
>>iterator as 'v.end()', which is a valid iterator that corresponds
>>to "one element past the last one". The same way as the pointer
>>obtained by adding the size of the array to the pointer of the
>>first element of the array is a valid pointer:
>>
>
>
> int main ()
> {
> std::vector<int> v;
> assert (v.begin() != v.end ());
> }
>
> The assertion fails on my implimentation.
And on any conforming implementation: for any standard
container c,
c.size() == std::distance(c.begin(), c.end());
always holds (indeed, something pretty similar is used
as the definition of size() in the standard IIRC).
-- James.
---
[ 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: v.Abazarov@attAbi.com ("Victor Bazarov")
Date: Fri, 1 Aug 2003 22:30:25 +0000 (UTC) Raw View
"Dhruv" <dhruvbird@gmx.net> wrote...
> [...]
> Here are some of the notions that I have deveveloped over time. They may
> not be correct though: I want reasons as to where I'm going wrong.
>
> 1. What I have in mind when I write container.begin () is that I should
get
> an iterator to the first element in that container. If the container is
> empty, I don't know what begin() will return.
'begin()' will return the same value as 'end()' for an empty container.
Now you know.
> 2. container.end() returns 1 past the last element. If the container is
> empty even, begin () == end () should not hold true,
Why?
> eben though I know it
> does. I don't know why, but that's how my mind works??????
Change the way your mind works. All you need to do is to learn how
certain things work in some special situations. If you [somehow]
learned something incorrectly, you _have_to_ unlearn it. There is
no way around that.
> Then, again
> when I think that if the container is empty, then if I iterate using
> for_each, or something, this sort of scheme where begin() never equals
> end() will always show the container having a single element.
...or more.
> 3. push_back() inserts an element at the end of the sequence. If there is
> none, it creates one, and the elemnt becomes the head. Same for
> push_front().
Not the same. 'push_front' does not insert at the end. It inserts
at the beginning. You can think of them as short-hand for
insert(end(), value)
and
insert(begin(), value)
, respectively. That's how they are specified in the Standard, anyway.
> 4. I guess this is cheap, but in places I do use begin()==end() as a test
> for whether the container is empty. I should be using empty()......
Using 'begin() == end()' is less efficient because it has to construct
_two_ iterator objects, while 'empty()' doesn't [supposedly].
Victor
---
[ 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: kuyper@wizard.net (James Kuyper)
Date: Sat, 2 Aug 2003 18:01:53 +0000 (UTC) Raw View
jdennett@acm.org (James Dennett) wrote in message news:<9H0Wa.4281$Ye.115@fed1read02>...
...
> And on any conforming implementation: for any standard
> container c,
> c.size() == std::distance(c.begin(), c.end());
> always holds (indeed, something pretty similar is used
> as the definition of size() in the standard IIRC).
The actual definition is c.end()-c.begin(). That's a little odd, since
only bi-directional and random-access iterators are required to
support the binary operator-(), and general containers aren't required
to use such iterators as their pointer type.
---
[ 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: jdennett@acm.org (James Dennett)
Date: Sat, 2 Aug 2003 21:36:13 +0000 (UTC) Raw View
James Kuyper wrote:
> jdennett@acm.org (James Dennett) wrote in message news:<9H0Wa.4281$Ye.115@fed1read02>...
> ...
>
>>And on any conforming implementation: for any standard
>>container c,
>> c.size() == std::distance(c.begin(), c.end());
>>always holds (indeed, something pretty similar is used
>>as the definition of size() in the standard IIRC).
>
>
> The actual definition is c.end()-c.begin(). That's a little odd, since
> only bi-directional and random-access iterators are required to
> support the binary operator-(), and general containers aren't required
> to use such iterators as their pointer type.
Indeed. The same short-cut is used in the descriptions
of algorithms, but there we have 25/9, which says
"In the description of the algorithms operators + and -
are used for some of the iterator categories for which
they do not have to be defined. In these cases the
semantics of a+n is the same as that of
{ X tmp = a;
advance(tmp, n);
return tmp;
}
and that of b-a is the same as of return distance(a, b);"
My memory told me that there was similar language for the
containers library section, but I cannot now find this
stated, which on the fact of it means that a (pointless)
formal interpretation would say that std::list<T>::size()
is ill-formed at worst (which would seem to be a defect,
given that the standard says otherwise) or undefined (which
is, clearl, also entirely unacceptable). Now there's no
real doubt about what is meant, and every library will
"do the right thing" here. The tests I've written for my
own implementation use std::distance to test the relationship
between size(), begin() and end() rather than using the
operator- as specified in the container requirements.
-- James.
---
[ 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: kuyper@wizard.net (James Kuyper)
Date: Sun, 3 Aug 2003 20:18:37 +0000 (UTC) Raw View
jdennett@acm.org (James Dennett) wrote in message news:<H%VWa.4951$Ye.4349@fed1read02>...
...
> Indeed. The same short-cut is used in the descriptions
> of algorithms, but there we have 25/9, which says
> "In the description of the algorithms operators + and -
> are used for some of the iterator categories for which
> they do not have to be defined. In these cases the
> semantics of a+n is the same as that of
> { X tmp = a;
> advance(tmp, n);
> return tmp;
> }
> and that of b-a is the same as of return distance(a, b);"
I agree with you that something like this was intended to apply; It's
not clear to me that the standard actually says so.
> My memory told me that there was similar language for the
> containers library section, but I cannot now find this
> stated, which on the fact of it means that a (pointless)
> formal interpretation would say that std::list<T>::size()
> is ill-formed at worst (which would seem to be a defect,
> given that the standard says otherwise) or undefined (which
> is, clearl, also entirely unacceptable). ...
Actually, no. The standard clearly requires that c.size() have the
semantics c.end()-c.begin(). A formal interpretation would therefore
derive an implication that the iterator type for a container must
support binary operator-(), even if that is not a requirement for that
iterator's category. It's perfectly legal for an iterator type to
support operators in addition to the ones required by it's category.
A valid implementation of a container using forward iterators could
support operator-() only for end() and begin(), throw()ing an
exception when used on any other pair of iterator values.
---
[ 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: andys@despammed.com (Andy Sawyer)
Date: Tue, 5 Aug 2003 23:33:43 +0000 (UTC) Raw View
In article <vii85o5efbaha8@corp.supernews.com>,
on Fri, 1 Aug 2003 22:30:25 +0000 (UTC),
v.Abazarov@attAbi.com ("Victor Bazarov") wrote:
> "Dhruv" <dhruvbird@gmx.net> wrote...
>
>> 4. I guess this is cheap, but in places I do use begin()==end() as a test
>> for whether the container is empty. I should be using empty()......
>
> Using 'begin() == end()' is less efficient because it has to construct
> _two_ iterator objects, while 'empty()' doesn't [supposedly].
It would be a poor implementation where empty() wasn't at least as
efficient as begin()==end(). Even if empty() is implemented as
"return begin() == end()", it's still more expressive. Here are a few
ways of checking for an empty container:
if( c.begin() == c.end() ) { /* do stuff */ }
if( !c.size() ) { /* do stuff */ }
if( c.size() == 0 } { /* do stuff */ }
if( c.empty() ) { /* do stuff */ }
They're all semantically equivalent for an std::container, but only one
of the actually says, in so many words, that it's a test for
emptiness. Similarly, if you want to test for a container being
non-empty, then:
if( c.begin() != c.end() ) { /* do stuff */ }
if( c.size() ) { /* do stuff */ }
if( c.size() != 0 } { /* do stuff */ }
if( !c.empty() ) { /* do stuff */ }
Again, only one of them says exactly what the test is for. And again, it
would be a poor implementaiton where !c.empty() were any less efficient
than any of the others.
Regards,
Andy S
--
"Light thinks it travels faster than anything but it is wrong. No matter
how fast light travels it finds the darkness has always got there first,
and is waiting for it." -- Terry Pratchett, Reaper Man
---
[ 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: "terjes."@chello.no (=?ISO-8859-1?Q?Terje_Sletteb=F8?=)
Date: Tue, 5 Aug 2003 23:34:08 +0000 (UTC) Raw View
rridge@csclub.uwaterloo.ca (Ross Ridge) wrote in message news:<bgc15i$6mj$1@tabloid.uwaterloo.ca>...
> <dhruvbird@gmx.net> writes
> >2. container.end() returns 1 past the last element.
>
> Francis Glassborow <francis@robinton.demon.co.uk> wrote:
> >I think that is an understandable but slightly inaccurate view. .end()
> >is required to return an iterator that somehow identifies that you have
> >finished. In the case of vectors this would be equivalent to the array's
> >one past the last element However in the case of a list, map etc. there
> >is no such thing just a special iterator that is valid but cannot be
> >dereferenced.
>
> It's just as true if the container is a list, map, or whatever. If "i"
> is an iterator that refers to the last element in the container "a",
> then "++i == a.end()" is true no matter what kind of container "a" is.
The point is that "a.end()" does not have to return "one past the last
element". For example for an empty array, it might return the null
pointer, if no array has been allocated yet.
> The problem with Dhruv's "view" is that it's meaningless when the
> container is empty and there is no last element
The problem is only if you use an incorrect meaning of the end()
iterator.
Regards,
Terje
---
[ 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: dhruvbird@gmx.net ("Dhruv")
Date: Tue, 29 Jul 2003 17:42:17 +0000 (UTC) Raw View
I wanted to know if this is considered valid C++?
I guess it should be UB, but could not find anything to that effect in the
standard document.
std::vector<int> v;
v.insert (v.begin(), 1);
Regards,
-Dhruv.
---
[ 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: ark@acm.org (Andrew Koenig)
Date: Tue, 29 Jul 2003 18:39:07 +0000 (UTC) Raw View
Dhruv> I wanted to know if this is considered valid C++?
Dhruv> std::vector<int> v;
Dhruv> v.insert (v.begin(), 1);
I don't see anything wrong with it. What do you think is the problem?
--
Andrew Koenig, ark@acm.org
---
[ 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 ]