Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #3599 > unrolled thread
| Started by | Nikos Chantziaras <realnc@arcor.de> |
|---|---|
| First post | 2011-04-14 00:38 +0300 |
| Last post | 2011-04-14 21:45 +0300 |
| Articles | 20 on this page of 24 — 9 participants |
Back to article view | Back to comp.lang.c++
Initializing iterators to one past end() in for loops Nikos Chantziaras <realnc@arcor.de> - 2011-04-14 00:38 +0300
Re: Initializing iterators to one past end() in for loops Leigh Johnston <leigh@i42.co.uk> - 2011-04-13 22:46 +0100
Re: Initializing iterators to one past end() in for loops Kai-Uwe Bux <jkherciueh@gmx.net> - 2011-04-13 23:48 +0200
Re: Initializing iterators to one past end() in for loops Leigh Johnston <leigh@i42.co.uk> - 2011-04-13 22:50 +0100
Re: Initializing iterators to one past end() in for loops Kai-Uwe Bux <jkherciueh@gmx.net> - 2011-04-14 00:23 +0200
Re: Initializing iterators to one past end() in for loops Kai-Uwe Bux <jkherciueh@gmx.net> - 2011-04-14 00:32 +0200
Re: Initializing iterators to one past end() in for loops Noah Roberts <dont@email.me> - 2011-04-13 17:16 -0700
Re: Initializing iterators to one past end() in for loops Kai-Uwe Bux <jkherciueh@gmx.net> - 2011-04-14 05:57 +0200
Re: Initializing iterators to one past end() in for loops Leigh Johnston <leigh@i42.co.uk> - 2011-04-14 14:29 +0100
Re: Initializing iterators to one past end() in for loops Kai-Uwe Bux <jkherciueh@gmx.net> - 2011-04-14 17:57 +0200
Re: Initializing iterators to one past end() in for loops Leigh Johnston <leigh@i42.co.uk> - 2011-04-14 17:56 +0100
Re: Initializing iterators to one past end() in for loops Kai-Uwe Bux <jkherciueh@gmx.net> - 2011-04-14 19:33 +0200
Re: Initializing iterators to one past end() in for loops Noah Roberts <dont@email.me> - 2011-04-14 09:54 -0700
Re: Initializing iterators to one past end() in for loops Kai-Uwe Bux <jkherciueh@gmx.net> - 2011-04-14 20:08 +0200
Re: Initializing iterators to one past end() in for loops gwowen <gwowen@gmail.com> - 2011-04-13 14:49 -0700
Re: Initializing iterators to one past end() in for loops Sam <sam@email-scan.com> - 2011-04-13 16:58 -0500
Re: Initializing iterators to one past end() in for loops Nikos Chantziaras <realnc@arcor.de> - 2011-04-14 01:07 +0300
Re: Initializing iterators to one past end() in for loops Ian Collins <ian-news@hotmail.com> - 2011-04-14 10:12 +1200
Re: Initializing iterators to one past end() in for loops gwowen <gwowen@gmail.com> - 2011-04-13 15:24 -0700
Re: Initializing iterators to one past end() in for loops Paavo Helde <myfirstname@osa.pri.ee> - 2011-04-13 23:05 -0500
Re: Initializing iterators to one past end() in for loops Ian Collins <ian-news@hotmail.com> - 2011-04-14 16:20 +1200
Re: Initializing iterators to one past end() in for loops Paavo Helde <myfirstname@osa.pri.ee> - 2011-04-13 23:52 -0500
Re: Initializing iterators to one past end() in for loops Jeff Flinn <TriumphSprint2000@hotmail.com> - 2011-04-14 07:49 -0400
Re: Initializing iterators to one past end() in for loops Nikos Chantziaras <realnc@arcor.de> - 2011-04-14 21:45 +0300
Page 1 of 2 [1] 2 Next page →
| From | Nikos Chantziaras <realnc@arcor.de> |
|---|---|
| Date | 2011-04-14 00:38 +0300 |
| Subject | Initializing iterators to one past end() in for loops |
| Message-ID | <io554k$9hn$1@news.grnet.gr> |
Is there some simple way to convert this:
std::vector<int> vec;
// ...
for (size_t i = 1; i < vec.size(); ++i)
// do something with vec[i]
to a for-loop that uses iterators? I've tried:
typedef std::vector<int>::iterator it_t;
for (it_t i = vec.begin() + 1; i != vec.end(); ++i)
// do something with *i
but I'm not surprised that it doesn't work.
[toc] | [next] | [standalone]
| From | Leigh Johnston <leigh@i42.co.uk> |
|---|---|
| Date | 2011-04-13 22:46 +0100 |
| Message-ID | <17OdnRrTgaoHhDvQnZ2dnUVZ8gSdnZ2d@giganews.com> |
| In reply to | #3599 |
On 13/04/2011 22:38, Nikos Chantziaras wrote: > Is there some simple way to convert this: > > std::vector<int> vec; > // ... > for (size_t i = 1; i < vec.size(); ++i) > // do something with vec[i] > > to a for-loop that uses iterators? I've tried: > > typedef std::vector<int>::iterator it_t; > for (it_t i = vec.begin() + 1; i != vec.end(); ++i) > // do something with *i > > but I'm not surprised that it doesn't work. Simple: check that the vector is not empty before the for loop. /Leigh
[toc] | [prev] | [next] | [standalone]
| From | Kai-Uwe Bux <jkherciueh@gmx.net> |
|---|---|
| Date | 2011-04-13 23:48 +0200 |
| Message-ID | <io55na$qog$1@hoshi.visyn.net> |
| In reply to | #3599 |
Nikos Chantziaras wrote:
> Is there some simple way to convert this:
>
> std::vector<int> vec;
> // ...
> for (size_t i = 1; i < vec.size(); ++i)
> // do something with vec[i]
>
> to a for-loop that uses iterators? I've tried:
>
> typedef std::vector<int>::iterator it_t;
> for (it_t i = vec.begin() + 1; i != vec.end(); ++i)
> // do something with *i
>
> but I'm not surprised that it doesn't work.
Iterators for std::vector<> are random access. Hence, they are <-comparable
and you can add integers to them. So, you should be able to translate one-
to-one:
for ( std::vector<int>::iterator iter = vec.begin() + 1;
iter < vec.end(); ++ iter ) {
// do something with *iter
}
The stop-condition iter != vec.end() is broken for empty vectors.
Best,
Kai-Uwe Bux
[toc] | [prev] | [next] | [standalone]
| From | Leigh Johnston <leigh@i42.co.uk> |
|---|---|
| Date | 2011-04-13 22:50 +0100 |
| Message-ID | <J4GdnRzOQoMOhzvQnZ2dnUVZ8hednZ2d@giganews.com> |
| In reply to | #3604 |
On 13/04/2011 22:48, Kai-Uwe Bux wrote:
> Nikos Chantziaras wrote:
>
>> Is there some simple way to convert this:
>>
>> std::vector<int> vec;
>> // ...
>> for (size_t i = 1; i< vec.size(); ++i)
>> // do something with vec[i]
>>
>> to a for-loop that uses iterators? I've tried:
>>
>> typedef std::vector<int>::iterator it_t;
>> for (it_t i = vec.begin() + 1; i != vec.end(); ++i)
>> // do something with *i
>>
>> but I'm not surprised that it doesn't work.
>
> Iterators for std::vector<> are random access. Hence, they are<-comparable
> and you can add integers to them. So, you should be able to translate one-
> to-one:
>
> for ( std::vector<int>::iterator iter = vec.begin() + 1;
> iter< vec.end(); ++ iter ) {
> // do something with *iter
> }
If the vector is empty then surely vec.begin() + 1 is UB?
/Leigh
[toc] | [prev] | [next] | [standalone]
| From | Kai-Uwe Bux <jkherciueh@gmx.net> |
|---|---|
| Date | 2011-04-14 00:23 +0200 |
| Message-ID | <io57ov$rjf$1@hoshi.visyn.net> |
| In reply to | #3607 |
Leigh Johnston wrote:
> On 13/04/2011 22:48, Kai-Uwe Bux wrote:
>> Nikos Chantziaras wrote:
>>
>>> Is there some simple way to convert this:
>>>
>>> std::vector<int> vec;
>>> // ...
>>> for (size_t i = 1; i< vec.size(); ++i)
>>> // do something with vec[i]
>>>
>>> to a for-loop that uses iterators? I've tried:
>>>
>>> typedef std::vector<int>::iterator it_t;
>>> for (it_t i = vec.begin() + 1; i != vec.end(); ++i)
>>> // do something with *i
>>>
>>> but I'm not surprised that it doesn't work.
>>
>> Iterators for std::vector<> are random access. Hence, they
>> are<-comparable and you can add integers to them. So, you should be able
>> to translate one- to-one:
>>
>> for ( std::vector<int>::iterator iter = vec.begin() + 1;
>> iter< vec.end(); ++ iter ) {
>> // do something with *iter
>> }
>
> If the vector is empty then surely vec.begin() + 1 is UB?
Hm, my first impulse was to say: "oh, true; that kills it". However, upon
looking up table 76 in the standard, it appears that
r += n
has no pre-condition (like r is dereferencable). Now, r+n is defined in
terms of r += n. Also, the dereferencability precondition is mentioned at
other places (e.g., for ++r in table 74 about forward iterators). So, maybe
vec.begin()+1 is not undefined behavior after all. Of course, it could also
be an omission in the standard, or it could be that I am too tired to figure
it out correctly.
Best,
Kai-Uwe Bux
[toc] | [prev] | [next] | [standalone]
| From | Kai-Uwe Bux <jkherciueh@gmx.net> |
|---|---|
| Date | 2011-04-14 00:32 +0200 |
| Message-ID | <io5893$rjf$2@hoshi.visyn.net> |
| In reply to | #3616 |
Kai-Uwe Bux wrote:
> Leigh Johnston wrote:
>
>> On 13/04/2011 22:48, Kai-Uwe Bux wrote:
>>> Nikos Chantziaras wrote:
>>>
>>>> Is there some simple way to convert this:
>>>>
>>>> std::vector<int> vec;
>>>> // ...
>>>> for (size_t i = 1; i< vec.size(); ++i)
>>>> // do something with vec[i]
>>>>
>>>> to a for-loop that uses iterators? I've tried:
>>>>
>>>> typedef std::vector<int>::iterator it_t;
>>>> for (it_t i = vec.begin() + 1; i != vec.end(); ++i)
>>>> // do something with *i
>>>>
>>>> but I'm not surprised that it doesn't work.
>>>
>>> Iterators for std::vector<> are random access. Hence, they
>>> are<-comparable and you can add integers to them. So, you should be able
>>> to translate one- to-one:
>>>
>>> for ( std::vector<int>::iterator iter = vec.begin() + 1;
>>> iter< vec.end(); ++ iter ) {
>>> // do something with *iter
>>> }
>>
>> If the vector is empty then surely vec.begin() + 1 is UB?
>
> Hm, my first impulse was to say: "oh, true; that kills it". However, upon
> looking up table 76 in the standard, it appears that
>
> r += n
>
> has no pre-condition (like r is dereferencable). Now, r+n is defined in
> terms of r += n. Also, the dereferencability precondition is mentioned at
> other places (e.g., for ++r in table 74 about forward iterators). So,
> maybe vec.begin()+1 is not undefined behavior after all. Of course, it
> could also be an omission in the standard, or it could be that I am too
> tired to figure it out correctly.
Seems, it was the third option:
[24.1/5] Iterators can also have singular values that are not associated
with any container. [Example: After the declaration of an uninitialized
pointer x (as with int* x;), x must always be assumed to have a singular
value of a pointer. ] Results of most expressions are undefined for
singular values; the only exception is an assignment of a non-singular
value to an iterator that holds a singular value. In this case the
singular value is overwritten the same way as any other value.
Dereferenceable values are always non-singular.
Hence, vec.begin()+1 is not UB (as vec.begin() is non-singular), but
assigning the resulting singular value to the iterator variable iter is UB.
Best,
Kai-Uwe Bux
[toc] | [prev] | [next] | [standalone]
| From | Noah Roberts <dont@email.me> |
|---|---|
| Date | 2011-04-13 17:16 -0700 |
| Message-ID | <4da63ccd$0$14279$cc2e38e6@news.uslec.net> |
| In reply to | #3619 |
On 4/13/2011 3:32 PM, Kai-Uwe Bux wrote:
> Kai-Uwe Bux wrote:
>
>> Leigh Johnston wrote:
>>
>>> On 13/04/2011 22:48, Kai-Uwe Bux wrote:
>>>> Nikos Chantziaras wrote:
>>>>
>>>>> Is there some simple way to convert this:
>>>>>
>>>>> std::vector<int> vec;
>>>>> // ...
>>>>> for (size_t i = 1; i< vec.size(); ++i)
>>>>> // do something with vec[i]
>>>>>
>>>>> to a for-loop that uses iterators? I've tried:
>>>>>
>>>>> typedef std::vector<int>::iterator it_t;
>>>>> for (it_t i = vec.begin() + 1; i != vec.end(); ++i)
>>>>> // do something with *i
>>>>>
>>>>> but I'm not surprised that it doesn't work.
>>>>
>>>> Iterators for std::vector<> are random access. Hence, they
>>>> are<-comparable and you can add integers to them. So, you should be able
>>>> to translate one- to-one:
>>>>
>>>> for ( std::vector<int>::iterator iter = vec.begin() + 1;
>>>> iter< vec.end(); ++ iter ) {
>>>> // do something with *iter
>>>> }
>>>
>>> If the vector is empty then surely vec.begin() + 1 is UB?
>>
>> Hm, my first impulse was to say: "oh, true; that kills it". However, upon
>> looking up table 76 in the standard, it appears that
>>
>> r += n
>>
>> has no pre-condition (like r is dereferencable). Now, r+n is defined in
>> terms of r += n. Also, the dereferencability precondition is mentioned at
>> other places (e.g., for ++r in table 74 about forward iterators). So,
>> maybe vec.begin()+1 is not undefined behavior after all. Of course, it
>> could also be an omission in the standard, or it could be that I am too
>> tired to figure it out correctly.
>
> Seems, it was the third option:
>
> [24.1/5] Iterators can also have singular values that are not associated
> with any container. [Example: After the declaration of an uninitialized
> pointer x (as with int* x;), x must always be assumed to have a singular
> value of a pointer. ] Results of most expressions are undefined for
> singular values; the only exception is an assignment of a non-singular
> value to an iterator that holds a singular value. In this case the
> singular value is overwritten the same way as any other value.
> Dereferenceable values are always non-singular.
>
> Hence, vec.begin()+1 is not UB (as vec.begin() is non-singular), but
> assigning the resulting singular value to the iterator variable iter is UB.
The problem here though is that if you where interpreting correctly then
pointers could not be iterators since (arr + sizeof(arr))++ is UB.
Luckily I believe you're interpreting incorrectly. The quote you show
there quite explicitly calls "most expressions are undefined...". The
only exception it provides is assignment FROM a non-singular. It seems
to be quite clearly illustrating that default constructed and
uninitialized iterators can exist but that you'd better not do anything
with them but assign to them from a valid iterator value that actually
iterates something. Further it isn't allowing for incrementing an
iterator past end().
--
http://crazycpp.wordpress.com
[toc] | [prev] | [next] | [standalone]
| From | Kai-Uwe Bux <jkherciueh@gmx.net> |
|---|---|
| Date | 2011-04-14 05:57 +0200 |
| Message-ID | <io5rak$3a4$1@hoshi.visyn.net> |
| In reply to | #3629 |
Noah Roberts wrote:
> On 4/13/2011 3:32 PM, Kai-Uwe Bux wrote:
>> Kai-Uwe Bux wrote:
>>
>>> Leigh Johnston wrote:
>>>
>>>> On 13/04/2011 22:48, Kai-Uwe Bux wrote:
>>>>> Nikos Chantziaras wrote:
>>>>>
>>>>>> Is there some simple way to convert this:
>>>>>>
>>>>>> std::vector<int> vec;
>>>>>> // ...
>>>>>> for (size_t i = 1; i< vec.size(); ++i)
>>>>>> // do something with vec[i]
>>>>>>
>>>>>> to a for-loop that uses iterators? I've tried:
>>>>>>
>>>>>> typedef std::vector<int>::iterator it_t;
>>>>>> for (it_t i = vec.begin() + 1; i != vec.end(); ++i)
>>>>>> // do something with *i
>>>>>>
>>>>>> but I'm not surprised that it doesn't work.
>>>>>
>>>>> Iterators for std::vector<> are random access. Hence, they
>>>>> are<-comparable and you can add integers to them. So, you should be
>>>>> able to translate one- to-one:
>>>>>
>>>>> for ( std::vector<int>::iterator iter = vec.begin() + 1;
>>>>> iter< vec.end(); ++ iter ) {
>>>>> // do something with *iter
>>>>> }
>>>>
>>>> If the vector is empty then surely vec.begin() + 1 is UB?
>>>
>>> Hm, my first impulse was to say: "oh, true; that kills it". However,
>>> upon looking up table 76 in the standard, it appears that
>>>
>>> r += n
>>>
>>> has no pre-condition (like r is dereferencable). Now, r+n is defined in
>>> terms of r += n. Also, the dereferencability precondition is mentioned
>>> at other places (e.g., for ++r in table 74 about forward iterators). So,
>>> maybe vec.begin()+1 is not undefined behavior after all. Of course, it
>>> could also be an omission in the standard, or it could be that I am too
>>> tired to figure it out correctly.
>>
>> Seems, it was the third option:
>>
>> [24.1/5] Iterators can also have singular values that are not
>> [associated
>> with any container. [Example: After the declaration of an
>> uninitialized pointer x (as with int* x;), x must always be assumed to
>> have a singular value of a pointer. ] Results of most expressions are
>> undefined for singular values; the only exception is an assignment of
>> a non-singular value to an iterator that holds a singular value. In
>> this case the singular value is overwritten the same way as any other
>> value. Dereferenceable values are always non-singular.
>>
>> Hence, vec.begin()+1 is not UB (as vec.begin() is non-singular), but
>> assigning the resulting singular value to the iterator variable iter is
>> UB.
>
> The problem here though is that if you where interpreting correctly then
> pointers could not be iterators since (arr + sizeof(arr))++ is UB.
a) Why would that be UB according to my interpretation of [24.1/5]?
b) It seems UB for iterators according to table 74: r++ is defined in terms
of ++r which needs r to be dereferencable.
c) Why would it be bad if this expression involved UB?
d) Is sizeof(arr) really what you mean?
> Luckily I believe you're interpreting incorrectly. The quote you show
> there quite explicitly calls "most expressions are undefined...". The
> only exception it provides is assignment FROM a non-singular.
Exactly. I have a cold, so maybe my brain is not working properly; but the
way I read [24.1/5] is as follows:
iterator iter = vec.begin(); // iter holds non-singular value.
vec.begin() + 1; // vec.begin() is a non-singular operand
iter = vec.begin() + 1; // if vec is empty, the rhs is singular.
// the operation of assignment is UB.
> It seems
> to be quite clearly illustrating that default constructed and
> uninitialized iterators can exist but that you'd better not do anything
> with them but assign to them from a valid iterator value that actually
> iterates something. Further it isn't allowing for incrementing an
> iterator past end().
Well, vec.end() is a non-singular value. Hence, the expression vec.end()+1
has a singular _result_ but the operands are non-singular. The way I read
[24.1/5] is that the result is defined although singular, i.e., I take the
phrase
Results of most expressions are undefined for singular values
to mean "undefined for singular values of the operands".
Something that also stirs up my curiosity is whether destructing an iterator
object that holds a singular value is UB.
Best,
Kai-Uwe Bux
[toc] | [prev] | [next] | [standalone]
| From | Leigh Johnston <leigh@i42.co.uk> |
|---|---|
| Date | 2011-04-14 14:29 +0100 |
| Message-ID | <weudnVZcmYU0azvQnZ2dnUVZ8sydnZ2d@giganews.com> |
| In reply to | #3635 |
On 14/04/2011 04:57, Kai-Uwe Bux wrote: > > Something that also stirs up my curiosity is whether destructing an iterator > object that holds a singular value is UB. > Not UB according to the Standard. /Leigh
[toc] | [prev] | [next] | [standalone]
| From | Kai-Uwe Bux <jkherciueh@gmx.net> |
|---|---|
| Date | 2011-04-14 17:57 +0200 |
| Message-ID | <io75hu$iu6$1@hoshi.visyn.net> |
| In reply to | #3673 |
Leigh Johnston wrote: > On 14/04/2011 04:57, Kai-Uwe Bux wrote: >> >> Something that also stirs up my curiosity is whether destructing an >> iterator object that holds a singular value is UB. >> > > Not UB according to the Standard. Good to know. Do you have chapter and verse where the behavior is defined? Best, Kai-Uwe Bux
[toc] | [prev] | [next] | [standalone]
| From | Leigh Johnston <leigh@i42.co.uk> |
|---|---|
| Date | 2011-04-14 17:56 +0100 |
| Message-ID | <V_2dnS9ujayyujrQnZ2dnUVZ7sednZ2d@giganews.com> |
| In reply to | #3683 |
On 14/04/2011 16:57, Kai-Uwe Bux wrote: > Leigh Johnston wrote: > >> On 14/04/2011 04:57, Kai-Uwe Bux wrote: >>> >>> Something that also stirs up my curiosity is whether destructing an >>> iterator object that holds a singular value is UB. >>> >> >> Not UB according to the Standard. > > Good to know. Do you have chapter and verse where the behavior is defined? > 24.2.1/5 /Leigh
[toc] | [prev] | [next] | [standalone]
| From | Kai-Uwe Bux <jkherciueh@gmx.net> |
|---|---|
| Date | 2011-04-14 19:33 +0200 |
| Message-ID | <io7b58$kuh$1@hoshi.visyn.net> |
| In reply to | #3702 |
Leigh Johnston wrote: > On 14/04/2011 16:57, Kai-Uwe Bux wrote: >> Leigh Johnston wrote: >> >>> On 14/04/2011 04:57, Kai-Uwe Bux wrote: >>>> >>>> Something that also stirs up my curiosity is whether destructing an >>>> iterator object that holds a singular value is UB. >>>> >>> >>> Not UB according to the Standard. >> >> Good to know. Do you have chapter and verse where the behavior is >> defined? >> > > 24.2.1/5 Ah, you are referring to C++0X. Thanks, Kai-Uwe Bux
[toc] | [prev] | [next] | [standalone]
| From | Noah Roberts <dont@email.me> |
|---|---|
| Date | 2011-04-14 09:54 -0700 |
| Message-ID | <4da726ca$0$17551$cc2e38e6@news.uslec.net> |
| In reply to | #3635 |
On 4/13/2011 8:57 PM, Kai-Uwe Bux wrote: > Noah Roberts wrote: > >> On 4/13/2011 3:32 PM, Kai-Uwe Bux wrote: >>> Kai-Uwe Bux wrote: >>> Seems, it was the third option: >>> >>> [24.1/5] Iterators can also have singular values that are not >>> [associated >>> with any container. [Example: After the declaration of an >>> uninitialized pointer x (as with int* x;), x must always be assumed to >>> have a singular value of a pointer. ] Results of most expressions are >>> undefined for singular values; the only exception is an assignment of >>> a non-singular value to an iterator that holds a singular value. In >>> this case the singular value is overwritten the same way as any other >>> value. Dereferenceable values are always non-singular. >>> >>> Hence, vec.begin()+1 is not UB (as vec.begin() is non-singular), but >>> assigning the resulting singular value to the iterator variable iter is >>> UB. >> >> The problem here though is that if you where interpreting correctly then >> pointers could not be iterators since [incrementing past the past-the-end iterator] is UB. > > a) Why would that be UB according to my interpretation of [24.1/5]? It's not. It's UB because incrementing a pointer beyond what the standard explicitly allows (for example 1 past the end of an array) is UB. Thus if your interpretation of the quoted bits where accurate, std::vector<T>::iterator could not be a pointer because past_end_ptr+1 is not defined, regardless of if its assigned to anything. > c) Why would it be bad if this expression involved UB? Practically speaking, most of the time, you probably wouldn't notice any unexpected behavior from this particular kind of UB. > > Exactly. I have a cold, so maybe my brain is not working properly; but the > way I read [24.1/5] is as follows: > > iterator iter = vec.begin(); // iter holds non-singular value. > vec.begin() + 1; // vec.begin() is a non-singular operand > iter = vec.begin() + 1; // if vec is empty, the rhs is singular. > // the operation of assignment is UB. 24.1/5 isn't actually saying anything about "non-singular values" except how assignment of them into previously singular iterators works. You can't use 24.1/5 as evidence that vec.begin() + 1 is defined when vec.empty() == true. > >> It seems >> to be quite clearly illustrating that default constructed and >> uninitialized iterators can exist but that you'd better not do anything >> with them but assign to them from a valid iterator value that actually >> iterates something. Further it isn't allowing for incrementing an >> iterator past end(). > > Well, vec.end() is a non-singular value. Hence, the expression vec.end()+1 > has a singular _result_ but the operands are non-singular. The way I read > [24.1/5] is that the result is defined although singular, i.e., I take the > phrase > > Results of most expressions are undefined for singular values > > to mean "undefined for singular values of the operands". To show that it's not defined, we first have to realize that if it's not defined by the standard it's as UB as if the standard specifically says so. If you note table 76, r + n is defined in terms of r+= n, which is defined in terms of r+n. r+n is defined in terms of ++r. The precondition for r in this case is that it is dereferenceable (24.1/5. Since end() is not, ++end() is not defined. Since ++end() is not defined, neither is end() + n. Based on these clauses and tables it would seem to me that the only way to get "singular" iterators is to not initialize an iterator. There's no defined way to get one from a non-singular iterator because any operation that could create one is not defined to do anything in particular by the standard. In some cases (and I've written them) ++end() will crash or do something really stupid like return end(). -- http://crazycpp.wordpress.com
[toc] | [prev] | [next] | [standalone]
| From | Kai-Uwe Bux <jkherciueh@gmx.net> |
|---|---|
| Date | 2011-04-14 20:08 +0200 |
| Message-ID | <io7d7a$lj2$1@hoshi.visyn.net> |
| In reply to | #3701 |
Noah Roberts wrote: > On 4/13/2011 8:57 PM, Kai-Uwe Bux wrote: >> Noah Roberts wrote: >> >>> On 4/13/2011 3:32 PM, Kai-Uwe Bux wrote: >>>> Kai-Uwe Bux wrote: > >>>> Seems, it was the third option: >>>> >>>> [24.1/5] Iterators can also have singular values that are not >>>> [associated >>>> with any container. [Example: After the declaration of an >>>> uninitialized pointer x (as with int* x;), x must always be assumed >>>> to have a singular value of a pointer. ] Results of most >>>> expressions are undefined for singular values; the only exception >>>> is an assignment of a non-singular value to an iterator that holds >>>> a singular value. In this case the singular value is overwritten >>>> the same way as any other value. Dereferenceable values are always >>>> non-singular. >>>> >>>> Hence, vec.begin()+1 is not UB (as vec.begin() is non-singular), but >>>> assigning the resulting singular value to the iterator variable iter is >>>> UB. >>> >>> The problem here though is that if you where interpreting correctly then >>> pointers could not be iterators since [incrementing past the >>> past-the-end iterator] is UB. >> >> a) Why would that be UB according to my interpretation of [24.1/5]? > > It's not. It's UB because incrementing a pointer beyond what the > standard explicitly allows (for example 1 past the end of an array) is > UB. Thus if your interpretation of the quoted bits where accurate, > std::vector<T>::iterator could not be a pointer because past_end_ptr+1 > is not defined, regardless of if its assigned to anything. Just to make sure, I grok the logic here: 1) For a pointer, past_end_ptr+1 is undefined. 2) According to my interpretation, vec.end()+1 is defined (as long as not assigned to anything). 3) Hence: std::vector<T>::iterator could not be a pointer. I would phrase that point differently: under the proposed interpretation, pointers would not satisfy the requirements for random access iterators. >> c) Why would it be bad if this expression involved UB? > > Practically speaking, most of the time, you probably wouldn't notice any > unexpected behavior from this particular kind of UB. > >> >> Exactly. I have a cold, so maybe my brain is not working properly; but >> the way I read [24.1/5] is as follows: >> >> iterator iter = vec.begin(); // iter holds non-singular value. >> vec.begin() + 1; // vec.begin() is a non-singular operand >> iter = vec.begin() + 1; // if vec is empty, the rhs is singular. >> // the operation of assignment is UB. > > 24.1/5 isn't actually saying anything about "non-singular values" except > how assignment of them into previously singular iterators works. You > can't use 24.1/5 as evidence that vec.begin() + 1 is defined when > vec.empty() == true. >> >>> It seems >>> to be quite clearly illustrating that default constructed and >>> uninitialized iterators can exist but that you'd better not do anything >>> with them but assign to them from a valid iterator value that actually >>> iterates something. Further it isn't allowing for incrementing an >>> iterator past end(). >> >> Well, vec.end() is a non-singular value. Hence, the expression >> vec.end()+1 has a singular _result_ but the operands are non-singular. >> The way I read >> [24.1/5] is that the result is defined although singular, i.e., I take >> [the >> phrase >> >> Results of most expressions are undefined for singular values >> >> to mean "undefined for singular values of the operands". > > To show that it's not defined, we first have to realize that if it's not > defined by the standard it's as UB as if the standard specifically says > so. If you note table 76, r + n is defined in terms of r+= n, which is > defined in terms of r+n. r+n is defined in terms of ++r. The > precondition for r in this case is that it is dereferenceable (24.1/5. > Since end() is not, ++end() is not defined. Since ++end() is not > defined, neither is end() + n. This definition in terms of ++r is what I missed. Thanks. > Based on these clauses and tables it would seem to me that the only way > to get "singular" iterators is to not initialize an iterator. There's > no defined way to get one from a non-singular iterator because any > operation that could create one is not defined to do anything in > particular by the standard. In some cases (and I've written them) > ++end() will crash or do something really stupid like return end(). Yup, seems that way. Best, Kai-Uwe Bux
[toc] | [prev] | [next] | [standalone]
| From | gwowen <gwowen@gmail.com> |
|---|---|
| Date | 2011-04-13 14:49 -0700 |
| Message-ID | <3b15728a-c425-4df6-b071-cd73c019fdd2@w7g2000pre.googlegroups.com> |
| In reply to | #3599 |
On Apr 13, 10:38 pm, Nikos Chantziaras <rea...@arcor.de> wrote: > typedef std::vector<int>::iterator it_t; > for (it_t i = vec.begin() + 1; i != vec.end(); ++i) > // do something with *i Unless you've got an empty vector, that should pretty much do it, unless the "do something with it" modifies the vector in such a way to invalidate the iterator (inserting elements will do this). If you have an empty vector, vec.begin() == vec.end(), so vec.begin() + 1 will be beyond the allowable range of iterators and bad things will happen. [To operate on every element want vec.begin(), not vec.begin() + 1 but you seem to be deliberately omitting the first element in both code samples, so I'm going to assume thats intentional.]
[toc] | [prev] | [next] | [standalone]
| From | Sam <sam@email-scan.com> |
|---|---|
| Date | 2011-04-13 16:58 -0500 |
| Message-ID | <cone.1302731935.197306.29607.500@monster.email-scan.com> |
| In reply to | #3599 |
[Multipart message — attachments visible in raw view] — view raw
Nikos Chantziaras writes: > Is there some simple way to convert this: > > std::vector<int> vec; > // ... > for (size_t i = 1; i < vec.size(); ++i) > // do something with vec[i] Any reference to vec[vec.size()] is undefined behavior. > to a for-loop that uses iterators? I've tried: > > typedef std::vector<int>::iterator it_t; > for (it_t i = vec.begin() + 1; i != vec.end(); ++i) > // do something with *i > > but I'm not surprised that it doesn't work. That's because it's undefined behavior, as well. The only thing that's undefined behavior can be converted to, is more undefined behavior. However, the only time your iterator example produces undefined behavior, and "doesn't work" would be if vec is empty. As long as the vec array is not empty, your iterator will end up iterating over all elements of the array, except the first one.
[toc] | [prev] | [next] | [standalone]
| From | Nikos Chantziaras <realnc@arcor.de> |
|---|---|
| Date | 2011-04-14 01:07 +0300 |
| Message-ID | <io56qc$cu8$1@news.grnet.gr> |
| In reply to | #3599 |
On 04/14/2011 12:38 AM, Nikos Chantziaras wrote:
> Is there some simple way to convert this:
>
> std::vector<int> vec;
> // ...
> for (size_t i = 1; i < vec.size(); ++i)
> // do something with vec[i]
>
> to a for-loop that uses iterators? I've tried:
>
> typedef std::vector<int>::iterator it_t;
> for (it_t i = vec.begin() + 1; i != vec.end(); ++i)
> // do something with *i
>
> but I'm not surprised that it doesn't work.
Thanks for all the responses. But I've made a mistake in my provided
example :-P In the second loop, I'm using an std::list, not a vector:
std::list<int> lst;
typedef std::list<int>::iterator it_t;
for (it_t i = lst.begin() + 1; i != lst.end(); ++i)
// do something with *i
(Converting some vectors to lists was the reason I came across this in
the first place.)
I know it's not difficult to simply do something like:
it_t i = lst.begin();
++i;
for ( ; i != lst.end(); ++i)
but I was wondering whether there's some neat way to do that inside the
for header, so that 'i' will not stay in scope after the loop.
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2011-04-14 10:12 +1200 |
| Message-ID | <90mleiFeeiU10@mid.individual.net> |
| In reply to | #3611 |
On 04/14/11 10:07 AM, Nikos Chantziaras wrote: > On 04/14/2011 12:38 AM, Nikos Chantziaras wrote: >> Is there some simple way to convert this: >> >> std::vector<int> vec; >> // ... >> for (size_t i = 1; i < vec.size(); ++i) >> // do something with vec[i] >> >> to a for-loop that uses iterators? I've tried: >> >> typedef std::vector<int>::iterator it_t; >> for (it_t i = vec.begin() + 1; i != vec.end(); ++i) >> // do something with *i >> >> but I'm not surprised that it doesn't work. > > Thanks for all the responses. But I've made a mistake in my provided > example :-P In the second loop, I'm using an std::list, not a vector: > > std::list<int> lst; > typedef std::list<int>::iterator it_t; > for (it_t i = lst.begin() + 1; i != lst.end(); ++i) > // do something with *i > > (Converting some vectors to lists was the reason I came across this in > the first place.) > > I know it's not difficult to simply do something like: > > it_t i = lst.begin(); > ++i; > for ( ; i != lst.end(); ++i) That would be the usual way. > but I was wondering whether there's some neat way to do that inside the > for header, so that 'i' will not stay in scope after the loop. Put the operation in its own scope (a function maybe)? -- Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | gwowen <gwowen@gmail.com> |
|---|---|
| Date | 2011-04-13 15:24 -0700 |
| Message-ID | <f2daf917-43a9-4775-a962-c06dc72d7e69@x12g2000prg.googlegroups.com> |
| In reply to | #3611 |
On Apr 13, 11:07 pm, Nikos Chantziaras <rea...@arcor.de> wrote:
> I know it's not difficult to simply do something like:
>
> it_t i = lst.begin();
> ++i;
> for ( ; i != lst.end(); ++i)
>
> but I was wondering whether there's some neat way to do that inside the
> for header, so that 'i' will not stay in scope after the loop.
Off the top of my, head and completely untested:
for(it_t it=l.begin(); ++it != l.end();){
std::cout << *it << std::endl;
}
(Again, you need to make sure you have started with an empty list...)
for(it_t it=l.begin(); (it != l.end() && ++it != l.end());){
std::cout << *it << std::endl;
}
It's not pretty, but it might work ;) Seems quite an ugly way to do it
when you can create a scope specifically for the iterator at the cost
of typing two braces.
[toc] | [prev] | [next] | [standalone]
| From | Paavo Helde <myfirstname@osa.pri.ee> |
|---|---|
| Date | 2011-04-13 23:05 -0500 |
| Message-ID | <Xns9EC7481B07908myfirstnameosapriee@216.196.109.131> |
| In reply to | #3611 |
Nikos Chantziaras <realnc@arcor.de> wrote in news:io56qc$cu8$1
@news.grnet.gr:
> Thanks for all the responses. But I've made a mistake in my provided
> example :-P In the second loop, I'm using an std::list, not a vector:
>
> std::list<int> lst;
> typedef std::list<int>::iterator it_t;
> for (it_t i = lst.begin() + 1; i != lst.end(); ++i)
> // do something with *i
>
> (Converting some vectors to lists was the reason I came across this in
> the first place.)
>
> I know it's not difficult to simply do something like:
>
> it_t i = lst.begin();
> ++i;
> for ( ; i != lst.end(); ++i)
>
> but I was wondering whether there's some neat way to do that inside the
> for header, so that 'i' will not stay in scope after the loop.
std::list<int> lst;
typedef std::list<int>::iterator it_t;
// populate list
if (!lst.empty()) {
for (it_t i = std::next(lst.begin()); i != lst.end(); ++i) {
// do something
}
}
cheers
Paavo
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.c++
csiph-web