Topic: iterator container::access(const_iterator);
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sat, 24 Aug 2013 06:20:59 -0700 (PDT)
Raw View
------=_Part_13_28970539.1377350459273
Content-Type: text/plain; charset=ISO-8859-1
On Saturday, August 24, 2013 4:39:57 AM UTC-7, Maurice Bos wrote:
>
> Hello,
>
> Since C++11, a lot of member functions of containers that used to take
> (non-const) iterators, now take const_iterators (such as insert, erase,
> etc.), since those member functions can only be called on non-const
> containers anyway and can thus modify it.
>
> However, what seems to be missing is to get a (non-const) iterator, given
> a non-const (reference to) a constainer and a const_iterator in it. For
> example:
>
> vector<int> a;
> vector<int>::const_iterator ci = a.cbegin();
> vector<int>::iterator i = a.access(ci); // turn it into a non-const
> iterator.
>
Um, no. That's like saying you have a `const &` to something and you want a
non-`const` reference to it. Yes, there's a way to do it, but you should
pretty much never employ it. If you were meant to have modifiable access to
the container, you wouldn't have been given a const_iterator to begin with.
Although this is already possible, there is currently no cross-container
> way do this in O(1):
>
> For a vector: auto i = a.begin() + (ci - a.begin());
> For a list: auto i = a.erase(ci, ci); // This is only guaranteed to be
> O(n) for a std::vector, although in most implementations this will be O(1)
>
> I needed this when i was making a class template called 'vectorset', which
> has the interface of a std set, but keeps its contents in a vector (or
> list, or deque, or anything else with a vector-like interface, depending on
> a template parameter). (It has less efficient inserting and erasing
> obviously, but it's more memory efficient and probably a better choice for,
> for example, a (mostly) constant set of just a few integers.) To make the
> insert member function take a const_iterator as hint, i needed to convert
> it to a non-const iterator, which can currently not be done in one way
> that's O(1) for all containers.
>
Why do you need to convert it to a non-const iterator? std::set::insert
only takes an iterator as a hint. If you're implementing a flat_set (which
BTW, Boost has already done for you<http://www.boost.org/doc/libs/1_54_0/doc/html/container/non_standard_containers.html#container.non_standard_containers.flat_xxx>),
you should use it to tell you the position in the array for where to start
looking. You don't need this position to be modifiable. You can convert it
into an array index easily enough, for example.
Or better yet, you can do whatever you want. It is, after all, *your*iterator; you can convert it into a non-const pointer to the array element
if you like. It can have whatever private interface on it you like. You are
not restricted to the same interface that you permit others to have.
You do not need to expose to others a public interface to do a const_cast
on your iterator. You just need to do that cast yourself.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_13_28970539.1377350459273
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Saturday, August 24, 2013 4:39:57 AM UTC-7, Maurice Bos=
wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.=
8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>H=
ello,<br><br>Since C++11, a lot of member functions of containers that used=
to take (non-const) iterators, now take const_iterators (such as insert, e=
rase, etc.), since those member functions can only be called on non-const c=
ontainers anyway and can thus modify it.<br>
<br>However, what seems to be missing is to get a (non-const) iterator, giv=
en a non-const (reference to) a constainer and a const_iterator in it. For =
example:<br><br>vector<int> a;<br></div>vector<int>::const_iter=
ator ci =3D a.cbegin();<br>
vector<int>::iterator i =3D a.access(ci); // turn it into a non-const=
iterator.<br></div></blockquote><div><br>Um, no. That's like saying you ha=
ve a `const &` to something and you want a non-`const` reference to it.=
Yes, there's a way to do it, but you should pretty much never employ it. I=
f you were meant to have modifiable access to the container, you wouldn't h=
ave been given a const_iterator to begin with.<br><br></div><blockquote cla=
ss=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #=
ccc solid;padding-left: 1ex;"><div dir=3D"ltr">Although this is already pos=
sible, there is currently no cross-container way do this in O(1):<br><br>Fo=
r a vector: auto i =3D a.begin() + (ci - a.begin());<br>
For a list: auto i =3D a.erase(ci, ci); // This is only guaranteed to be O(=
n) for a std::vector, although in most implementations this will be O(1)<br=
><br>I needed this when i was making a class template called 'vectorset', w=
hich has the interface of a std set, but keeps its contents in a vector (or=
list, or deque, or anything else with a vector-like interface, depending o=
n a template parameter). (It has less efficient inserting and erasing obvio=
usly, but it's more memory efficient and probably a better choice for, for =
example, a (mostly) constant set of just a few integers.) To make the inser=
t member function take a const_iterator as hint, i needed to convert it to =
a non-const iterator, which can currently not be done in one way that's O(1=
) for all containers.<br></div></blockquote><div><br>Why do you need to con=
vert it to a non-const iterator? std::set::insert only takes an iterator as=
a hint. If you're implementing a flat_set (which BTW, <a href=3D"http://ww=
w.boost.org/doc/libs/1_54_0/doc/html/container/non_standard_containers.html=
#container.non_standard_containers.flat_xxx">Boost has already done for you=
</a>), you should use it to tell you the position in the array for where to=
start looking. You don't need this position to be modifiable. You can conv=
ert it into an array index easily enough, for example.<br><br>Or better yet=
, you can do whatever you want. It is, after all, <i>your</i> iterator; you=
can convert it into a non-const pointer to the array element if you like. =
It can have whatever private interface on it you like. You are not restrict=
ed to the same interface that you permit others to have.<br><br>You do not =
need to expose to others a public interface to do a const_cast on your iter=
ator. You just need to do that cast yourself.<br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_13_28970539.1377350459273--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sat, 24 Aug 2013 16:34:40 +0300
Raw View
--001a11c3d73cd0873304e4b195be
Content-Type: text/plain; charset=ISO-8859-1
On 24 August 2013 14:39, Maurice Bos <m-ou.se@m-ou.se> wrote:
> Hello,
>
> Since C++11, a lot of member functions of containers that used to take
> (non-const) iterators, now take const_iterators (such as insert, erase,
> etc.), since those member functions can only be called on non-const
> containers anyway and can thus modify it.
>
> However, what seems to be missing is to get a (non-const) iterator, given
> a non-const (reference to) a constainer and a const_iterator in it. For
> example:
>
> vector<int> a;
> vector<int>::const_iterator ci = a.cbegin();
> vector<int>::iterator i = a.access(ci); // turn it into a non-const
> iterator.
>
> Although this is already possible, there is currently no cross-container
> way do this in O(1):
>
> For a vector: auto i = a.begin() + (ci - a.begin());
> For a list: auto i = a.erase(ci, ci); // This is only guaranteed to be
> O(n) for a std::vector, although in most implementations this will be O(1)
>
>
Isn't N==1 in the latter? Seems to me that erase(ci, ci) does what you want
on every container I can find.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--001a11c3d73cd0873304e4b195be
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><br><div class=3D"gmail=
_quote">On 24 August 2013 14:39, Maurice Bos <span dir=3D"ltr"><<a href=
=3D"mailto:m-ou.se@m-ou.se" target=3D"_blank">m-ou.se@m-ou.se</a>></span=
> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Hello,<br><br>Since C+=
+11, a lot of member functions of containers that used to take (non-const) =
iterators, now take const_iterators (such as insert, erase, etc.), since th=
ose member functions can only be called on non-const containers anyway and =
can thus modify it.<br>
<br>However, what seems to be missing is to get a (non-const) iterator, giv=
en a non-const (reference to) a constainer and a const_iterator in it. For =
example:<br><br>vector<int> a;<br></div>vector<int>::const_iter=
ator ci =3D a.cbegin();<br>
vector<int>::iterator i =3D a.access(ci); // turn it into a non-const=
iterator.<br><br>Although this is already possible, there is currently no =
cross-container way do this in O(1):<br><br>For a vector: auto i =3D a.begi=
n() + (ci - a.begin());<br>
For a list: auto i =3D a.erase(ci, ci); // This is only guaranteed to be O(=
n) for a std::vector, although in most implementations this will be O(1)<br=
><br></div></blockquote><div><br></div><div>Isn't N=3D=3D1 in the latte=
r? Seems to me that erase(ci, ci) does what you want on every container I c=
an find. <br>
</div></div><br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--001a11c3d73cd0873304e4b195be--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sat, 24 Aug 2013 16:39:57 +0300
Raw View
--047d7b33d374afca9404e4b1a8f6
Content-Type: text/plain; charset=ISO-8859-1
On 24 August 2013 16:34, Ville Voutilainen <ville.voutilainen@gmail.com>wrote:
>
>
>
> On 24 August 2013 14:39, Maurice Bos <m-ou.se@m-ou.se> wrote:
>
>> Hello,
>>
>> Since C++11, a lot of member functions of containers that used to take
>> (non-const) iterators, now take const_iterators (such as insert, erase,
>> etc.), since those member functions can only be called on non-const
>> containers anyway and can thus modify it.
>>
>> However, what seems to be missing is to get a (non-const) iterator, given
>> a non-const (reference to) a constainer and a const_iterator in it. For
>> example:
>>
>> vector<int> a;
>> vector<int>::const_iterator ci = a.cbegin();
>> vector<int>::iterator i = a.access(ci); // turn it into a non-const
>> iterator.
>>
>> Although this is already possible, there is currently no cross-container
>> way do this in O(1):
>>
>> For a vector: auto i = a.begin() + (ci - a.begin());
>> For a list: auto i = a.erase(ci, ci); // This is only guaranteed to be
>> O(n) for a std::vector, although in most implementations this will be O(1)
>>
>>
> Isn't N==1 in the latter? Seems to me that erase(ci, ci) does what you
> want on every container I can find.
>
>
Well, actually, erase(ci, ci) will return an iterator that'll point to
ci+1, so an additional operator-- is needed.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--047d7b33d374afca9404e4b1a8f6
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><br><div class=3D"gmail=
_quote">On 24 August 2013 16:34, Ville Voutilainen <span dir=3D"ltr"><<a=
href=3D"mailto:ville.voutilainen@gmail.com" target=3D"_blank">ville.voutil=
ainen@gmail.com</a>></span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br><div class=3D"gmail_ext=
ra"><br><br><div class=3D"gmail_quote"><div class=3D"im">On 24 August 2013 =
14:39, Maurice Bos <span dir=3D"ltr"><<a href=3D"mailto:m-ou.se@m-ou.se"=
target=3D"_blank">m-ou.se@m-ou.se</a>></span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Hello,<br><br>Since C+=
+11, a lot of member functions of containers that used to take (non-const) =
iterators, now take const_iterators (such as insert, erase, etc.), since th=
ose member functions can only be called on non-const containers anyway and =
can thus modify it.<br>
<br>However, what seems to be missing is to get a (non-const) iterator, giv=
en a non-const (reference to) a constainer and a const_iterator in it. For =
example:<br><br>vector<int> a;<br></div>vector<int>::const_iter=
ator ci =3D a.cbegin();<br>
vector<int>::iterator i =3D a.access(ci); // turn it into a non-const=
iterator.<br><br>Although this is already possible, there is currently no =
cross-container way do this in O(1):<br><br>For a vector: auto i =3D a.begi=
n() + (ci - a.begin());<br>
For a list: auto i =3D a.erase(ci, ci); // This is only guaranteed to be O(=
n) for a std::vector, although in most implementations this will be O(1)<br=
><br></div></blockquote><div><br></div></div><div>Isn't N=3D=3D1 in the=
latter? Seems to me that erase(ci, ci) does what you want on every contain=
er I can find. <br>
</div></div><br></div></div>
</blockquote></div><br></div><div class=3D"gmail_extra">Well, actually, era=
se(ci, ci) will return an iterator that'll point to ci+1, so an additio=
nal operator-- is needed.<br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--047d7b33d374afca9404e4b1a8f6--
.
Author: =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.kruegler@gmail.com>
Date: Sat, 24 Aug 2013 16:41:57 +0200
Raw View
2013/8/24 Ville Voutilainen <ville.voutilainen@gmail.com>:
>
> On 24 August 2013 16:34, Ville Voutilainen <ville.voutilainen@gmail.com>
> wrote:
>>
>>
>> On 24 August 2013 14:39, Maurice Bos <m-ou.se@m-ou.se> wrote:
>>>
>>> Hello,
>>>
>>> Since C++11, a lot of member functions of containers that used to take
>>> (non-const) iterators, now take const_iterators (such as insert, erase,
>>> etc.), since those member functions can only be called on non-const
>>> containers anyway and can thus modify it.
>>>
>>> However, what seems to be missing is to get a (non-const) iterator, given
>>> a non-const (reference to) a constainer and a const_iterator in it. For
>>> example:
>>>
>>> vector<int> a;
>>> vector<int>::const_iterator ci = a.cbegin();
>>> vector<int>::iterator i = a.access(ci); // turn it into a non-const
>>> iterator.
>>>
>>> Although this is already possible, there is currently no cross-container
>>> way do this in O(1):
>>>
>>> For a vector: auto i = a.begin() + (ci - a.begin());
>>> For a list: auto i = a.erase(ci, ci); // This is only guaranteed to be
>>> O(n) for a std::vector, although in most implementations this will be O(1)
>>>
>>
>> Isn't N==1 in the latter? Seems to me that erase(ci, ci) does what you
>> want on every container I can find.
>
> Well, actually, erase(ci, ci) will return an iterator that'll point to ci+1,
> so an additional operator-- is needed.
IMO, we shouldn't teach people to use tricky combinations of library
functionality to realize a well-defined coding pattern. C++11
respected that many iterator arguments that are part of some API
function are pure position specifiers. The access function suggested
above allows more than that, but it is still const-correct in all
respects, so I do disagree with Nicol that this is similar to a
const_cast. The presented workarounds (which look ugly to me and I
don't consider them as acceptable ones), just demonstrate that if I
have a non-const container I do have full access to what the interface
allows me to do - including "computing" the non-const iterator of a
given const_iterator. The access function would still be right for
sets, which are basically immutable, albeit of little advantage, but
IMO reasonable for symmetry reasons.
My personal recommendation would be to change the name, though,
because "access" sounds too generic to me. I remember that during some
committee meeting someone suggested a name along the side of
"to_iterator". I might even make sense to make this a free function
and allow ADL to find the right one, so we can use the same code
pattern for built-in arrays as well.
- Daniel
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sat, 24 Aug 2013 18:17:20 +0300
Raw View
--089e013cbae8f1d67604e4b3047b
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
On 24 August 2013 17:41, Daniel Kr=FCgler <daniel.kruegler@gmail.com> wrote=
:
> 2013/8/24 Ville Voutilainen <ville.voutilainen@gmail.com>:
> >
> > On 24 August 2013 16:34, Ville Voutilainen <ville.voutilainen@gmail.com=
>
> > wrote:
> >>
> >>
> >> On 24 August 2013 14:39, Maurice Bos <m-ou.se@m-ou.se> wrote:
> >>>
> >>> Hello,
> >>>
> >>> Since C++11, a lot of member functions of containers that used to tak=
e
> >>> (non-const) iterators, now take const_iterators (such as insert, eras=
e,
> >>> etc.), since those member functions can only be called on non-const
> >>> containers anyway and can thus modify it.
> >>>
> >>> However, what seems to be missing is to get a (non-const) iterator,
> given
> >>> a non-const (reference to) a constainer and a const_iterator in it. F=
or
> >>> example:
> >>>
> >>> vector<int> a;
> >>> vector<int>::const_iterator ci =3D a.cbegin();
> >>> vector<int>::iterator i =3D a.access(ci); // turn it into a non-const
> >>> iterator.
> >>>
> >>> Although this is already possible, there is currently no
> cross-container
> >>> way do this in O(1):
> >>>
> >>> For a vector: auto i =3D a.begin() + (ci - a.begin());
> >>> For a list: auto i =3D a.erase(ci, ci); // This is only guaranteed to=
be
> >>> O(n) for a std::vector, although in most implementations this will be
> O(1)
> >>>
> >>
> >> Isn't N=3D=3D1 in the latter? Seems to me that erase(ci, ci) does what=
you
> >> want on every container I can find.
> >
> > Well, actually, erase(ci, ci) will return an iterator that'll point to
> ci+1,
> > so an additional operator-- is needed.
>
> IMO, we shouldn't teach people to use tricky combinations of library
> functionality to realize a well-defined coding pattern. C++11
> respected that many iterator arguments that are part of some API
> function are pure position specifiers. The access function suggested
> above allows more than that, but it is still const-correct in all
> respects, so I do disagree with Nicol that this is similar to a
> const_cast. The presented workarounds (which look ugly to me and I
> don't consider them as acceptable ones), just demonstrate that if I
> have a non-const container I do have full access to what the interface
> allows me to do - including "computing" the non-const iterator of a
> given const_iterator. The access function would still be right for
> sets, which are basically immutable, albeit of little advantage, but
> IMO reasonable for symmetry reasons.
>
> My personal recommendation would be to change the name, though,
> because "access" sounds too generic to me. I remember that during some
> committee meeting someone suggested a name along the side of
> "to_iterator". I might even make sense to make this a free function
> and allow ADL to find the right one, so we can use the same code
> pattern for built-in arrays as well.
>
>
>
200% agreed. to_iterator() sounds fine to me. Let the bike-shedding begin.
:)
Want to co-author an LEWG paper? The target would likely be a library TS
and c++17 after that, I have no interest in pushing this into c++14.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--089e013cbae8f1d67604e4b3047b
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><br><div class=3D"gmail=
_quote">On 24 August 2013 17:41, Daniel Kr=FCgler <span dir=3D"ltr"><<a =
href=3D"mailto:daniel.kruegler@gmail.com" target=3D"_blank">daniel.kruegler=
@gmail.com</a>></span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">2013/8/24 Ville Voutilainen <<a href=3D"m=
ailto:ville.voutilainen@gmail.com">ville.voutilainen@gmail.com</a>>:<br>
<div><div class=3D"h5">><br>
> On 24 August 2013 16:34, Ville Voutilainen <<a href=3D"mailto:ville=
..voutilainen@gmail.com">ville.voutilainen@gmail.com</a>><br>
> wrote:<br>
>><br>
>><br>
>> On 24 August 2013 14:39, Maurice Bos <<a href=3D"mailto:m-ou.se=
@m-ou.se">m-ou.se@m-ou.se</a>> wrote:<br>
>>><br>
>>> Hello,<br>
>>><br>
>>> Since C++11, a lot of member functions of containers that used=
to take<br>
>>> (non-const) iterators, now take const_iterators (such as inser=
t, erase,<br>
>>> etc.), since those member functions can only be called on non-=
const<br>
>>> containers anyway and can thus modify it.<br>
>>><br>
>>> However, what seems to be missing is to get a (non-const) iter=
ator, given<br>
>>> a non-const (reference to) a constainer and a const_iterator i=
n it. For<br>
>>> example:<br>
>>><br>
>>> vector<int> a;<br>
>>> vector<int>::const_iterator ci =3D a.cbegin();<br>
>>> vector<int>::iterator i =3D a.access(ci); // turn it int=
o a non-const<br>
>>> iterator.<br>
>>><br>
>>> Although this is already possible, there is currently no cross=
-container<br>
>>> way do this in O(1):<br>
>>><br>
>>> For a vector: auto i =3D a.begin() + (ci - a.begin());<br>
>>> For a list: auto i =3D a.erase(ci, ci); // This is only guaran=
teed to be<br>
>>> O(n) for a std::vector, although in most implementations this =
will be O(1)<br>
>>><br>
>><br>
>> Isn't N=3D=3D1 in the latter? Seems to me that erase(ci, ci) d=
oes what you<br>
>> want on every container I can find.<br>
><br>
> Well, actually, erase(ci, ci) will return an iterator that'll poin=
t to ci+1,<br>
> so an additional operator-- is needed.<br>
<br>
</div></div>IMO, we shouldn't teach people to use tricky combinations o=
f library<br>
functionality to realize a well-defined coding pattern. C++11<br>
respected that many iterator arguments that are part of some API<br>
function are pure position specifiers. The access function suggested<br>
above allows more than that, but it is still const-correct in all<br>
respects, so I do disagree with Nicol that this is similar to a<br>
const_cast. The presented workarounds (which look ugly to me and I<br>
don't consider them as acceptable ones), just demonstrate that if I<br>
have a non-const container I do have full access to what the interface<br>
allows me to do - including "computing" the non-const iterator of=
a<br>
given const_iterator. The access function would still be right for<br>
sets, which are basically immutable, albeit of little advantage, but<br>
IMO reasonable for symmetry reasons.<br>
<br>
My personal recommendation would be to change the name, though,<br>
because "access" sounds too generic to me. I remember that during=
some<br>
committee meeting someone suggested a name along the side of<br>
"to_iterator". I might even make sense to make this a free functi=
on<br>
and allow ADL to find the right one, so we can use the same code<br>
pattern for built-in arrays as well.<br>
<span class=3D"HOEnZb"><font color=3D"#888888"><br><br></font></span></bloc=
kquote><div><br></div><div>200% agreed. to_iterator() sounds fine to me. Le=
t the bike-shedding begin. :)<br></div><div>Want to co-author an LEWG paper=
? The target would likely be a library TS<br>
and c++17 after that, I have no interest in pushing this into c++14. <br></=
div></div><br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--089e013cbae8f1d67604e4b3047b--
.
Author: =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.kruegler@gmail.com>
Date: Sat, 24 Aug 2013 17:20:35 +0200
Raw View
> 200% agreed. to_iterator() sounds fine to me. Let the bike-shedding begin.
> :)
> Want to co-author an LEWG paper?
Sure.
> The target would likely be a library TS
> and c++17 after that, I have no interest in pushing this into c++14.
I agree.
- Daniel
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Maurice Bos <m-ou.se@m-ou.se>
Date: Sat, 24 Aug 2013 19:08:17 +0200
Raw View
--001a11c23c88fbf64204e4b49289
Content-Type: text/plain; charset=ISO-8859-1
2013/8/24 Nicol Bolas <jmckesson@gmail.com>
>
> Um, no. That's like saying you have a `const &` to something and you want
> a non-`const` reference to it. Yes, there's a way to do it, but you should
> pretty much never employ it. If you were meant to have modifiable access to
> the container, you wouldn't have been given a const_iterator to begin with.
>
No, modifying functions like insert and erase take a const_iterator. So "If
you were meant to have modifiable access to the container, you wouldn't
have been given a const_iterator to begin with." is invalid.
> Why do you need to convert it to a non-const iterator? std::set::insert
> only takes an iterator as a hint. If you're implementing a flat_set (which
> BTW, Boost has already done for you<http://www.boost.org/doc/libs/1_54_0/doc/html/container/non_standard_containers.html#container.non_standard_containers.flat_xxx>),
> you should use it to tell you the position in the array for where to start
> looking. You don't need this position to be modifiable. You can convert it
> into an array index easily enough, for example.
>
"You can convert it into an array index easily enough"... Well, no, that's
my point. For arrays/vectors, yes, but you can't get do it in O(1) in a way
that works for all containers...
>
> Or better yet, you can do whatever you want. It is, after all, *your*iterator; you can convert it into a non-const pointer to the array element
> if you like. It can have whatever private interface on it you like. You are
> not restricted to the same interface that you permit others to have.
>
No, it isn't *my* iterator. The vectorset/flat_set/whatever just can just
use the iterators of the underlying container. It are vector/list/deque's
iterators, not 'my' iterators.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--001a11c23c88fbf64204e4b49289
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><div class=3D"gmail_extra"><div class=3D"gmail_quote">=
2013/8/24 Nicol Bolas <span dir=3D"ltr"><<a href=3D"mailto:jmckesson@gma=
il.com" target=3D"_blank">jmckesson@gmail.com</a>></span><br><blockquote=
class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px so=
lid rgb(204,204,204);padding-left:1ex">
<div dir=3D"ltr"><div><br>Um, no. That's like saying you have a `const =
&` to something and you want a non-`const` reference to it. Yes, there&=
#39;s a way to do it, but you should pretty much never employ it. If you we=
re meant to have modifiable access to the container, you wouldn't have =
been given a const_iterator to begin with.<br>
</div></div></blockquote><div><br>No, modifying functions like insert and e=
rase take a const_iterator. So "If you were meant to have modifiable a=
ccess to the container, you wouldn't have been given a const_iterator t=
o begin with." is invalid.<br>
<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8=
ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr=
"><div><br>Why do you need to convert it to a non-const iterator? std::set:=
:insert only takes an iterator as a hint. If you're implementing a flat=
_set (which BTW, <a href=3D"http://www.boost.org/doc/libs/1_54_0/doc/html/c=
ontainer/non_standard_containers.html#container.non_standard_containers.fla=
t_xxx" target=3D"_blank">Boost has already done for you</a>), you should us=
e it to tell you the position in the array for where to start looking. You =
don't need this position to be modifiable. You can convert it into an a=
rray index easily enough, for example.<br>
</div></div></blockquote><div><br>"You can convert it into an array in=
dex easily enough"... Well, no, that's my point. For arrays/vector=
s, yes, but you can't get do it in O(1) in a way that works for all con=
tainers...<br>
=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8e=
x;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"=
><div><br>Or better yet, you can do whatever you want. It is, after all, <i=
>your</i> iterator; you can convert it into a non-const pointer to the arra=
y element if you like. It can have whatever private interface on it you lik=
e. You are not restricted to the same interface that you permit others to h=
ave.<br>
</div></div></blockquote><div><br>No, it isn't *my* iterator. The vecto=
rset/flat_set/whatever just can just use the iterators of the underlying co=
ntainer. It are vector/list/deque's iterators, not 'my' iterato=
rs.<br>
</div></div></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--001a11c23c88fbf64204e4b49289--
.
Author: Maurice Bos <m-ou.se@m-ou.se>
Date: Sat, 24 Aug 2013 19:10:30 +0200
Raw View
--089e01493964dc801b04e4b49a0a
Content-Type: text/plain; charset=ISO-8859-1
2013/8/24 Ville Voutilainen <ville.voutilainen@gmail.com>
>
> For a vector: auto i = a.begin() + (ci - a.begin());
>> For a list: auto i = a.erase(ci, ci); // This is only guaranteed to be
>> O(n) for a std::vector, although in most implementations this will be O(1)
>>
>>
> Isn't N==1 in the latter? Seems to me that erase(ci, ci) does what you
> want on every container I can find.
>
>
In all implementations, probably. But according to the standard the move
constructor will be called std::distance(ci, a.end()) times, making it
O(distance(ci, a.end()). It doesn't describe a special case for when the
given range is empty.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--089e01493964dc801b04e4b49a0a
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><br><div class=3D"gmail=
_quote">2013/8/24 Ville Voutilainen <span dir=3D"ltr"><<a href=3D"mailto=
:ville.voutilainen@gmail.com" target=3D"_blank">ville.voutilainen@gmail.com=
</a>></span><br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br><div class=3D"gmail_ext=
ra"><div class=3D"gmail_quote"><div class=3D"im"><blockquote class=3D"gmail=
_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:=
1ex">
<div dir=3D"ltr">For a vector: auto i =3D a.begin() + (ci - a.begin());<br>
For a list: auto i =3D a.erase(ci, ci); // This is only guaranteed to be O(=
n) for a std::vector, although in most implementations this will be O(1)<br=
><br></div></blockquote><div><br></div></div><div>Isn't N=3D=3D1 in the=
latter? Seems to me that erase(ci, ci) does what you want on every contain=
er I can find. <br>
</div></div><br></div></div></blockquote><div><br>In all implementations, p=
robably. But according to the standard the move constructor will be called =
std::distance(ci, a.end()) times, making it O(distance(ci, a.end()). It doe=
sn't describe a special case for when the given range is empty.<br>
</div></div></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--089e01493964dc801b04e4b49a0a--
.
Author: Maurice Bos <m-ou.se@m-ou.se>
Date: Sat, 24 Aug 2013 19:17:40 +0200
Raw View
--e89a8f923ab0836d3904e4b4b49d
Content-Type: text/plain; charset=ISO-8859-1
2013/8/24 Ville Voutilainen <ville.voutilainen@gmail.com>
>
> Well, actually, erase(ci, ci) will return an iterator that'll point to
> ci+1, so an additional operator-- is needed.
>
>
>
Nope, that's not true. It gives the right iterator right away:
[sequence.reqmts]: "The iterator returned by a.erase(q1,q2) points to the
element pointed to by q2 prior to any elements being erased."
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--e89a8f923ab0836d3904e4b4b49d
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><br><div class=3D"gmail=
_quote">2013/8/24 Ville Voutilainen <span dir=3D"ltr"><<a href=3D"mailto=
:ville.voutilainen@gmail.com" target=3D"_blank">ville.voutilainen@gmail.com=
</a>></span><br>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div cla=
ss=3D"im"><br></div><div class=3D"gmail_extra">Well, actually, erase(ci, ci=
) will return an iterator that'll point to ci+1, so an additional opera=
tor-- is needed.<br>
</div></div><div class=3D""><div class=3D"h5">
<p></p><br></div></div></blockquote><div><br>Nope, that's not true. It =
gives the right iterator right away: [sequence.reqmts]: "The iterator =
returned by a.erase(q1,q2) points to the element pointed to by q2 prior to =
any elements being erased."<br>
</div></div></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--e89a8f923ab0836d3904e4b4b49d--
.
Author: Maurice Bos <m-ou.se@m-ou.se>
Date: Sat, 24 Aug 2013 19:20:41 +0200
Raw View
--047d7b3a89764d245304e4b4bf4e
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
to_iterator indeed sounds a lot better. :)
I'm sorry, but what does TS mean in 'library TS'? I don't recognize the
acronym. (I'm quite new to C++ standardization.)
2013/8/24 Ville Voutilainen <ville.voutilainen@gmail.com>
>
>
>
> On 24 August 2013 17:41, Daniel Kr=FCgler <daniel.kruegler@gmail.com> wro=
te:
>
>> 2013/8/24 Ville Voutilainen <ville.voutilainen@gmail.com>:
>> >
>> > On 24 August 2013 16:34, Ville Voutilainen <ville.voutilainen@gmail.co=
m
>> >
>> > wrote:
>> >>
>> >>
>> >> On 24 August 2013 14:39, Maurice Bos <m-ou.se@m-ou.se> wrote:
>> >>>
>> >>> Hello,
>> >>>
>> >>> Since C++11, a lot of member functions of containers that used to ta=
ke
>> >>> (non-const) iterators, now take const_iterators (such as insert,
>> erase,
>> >>> etc.), since those member functions can only be called on non-const
>> >>> containers anyway and can thus modify it.
>> >>>
>> >>> However, what seems to be missing is to get a (non-const) iterator,
>> given
>> >>> a non-const (reference to) a constainer and a const_iterator in it.
>> For
>> >>> example:
>> >>>
>> >>> vector<int> a;
>> >>> vector<int>::const_iterator ci =3D a.cbegin();
>> >>> vector<int>::iterator i =3D a.access(ci); // turn it into a non-cons=
t
>> >>> iterator.
>> >>>
>> >>> Although this is already possible, there is currently no
>> cross-container
>> >>> way do this in O(1):
>> >>>
>> >>> For a vector: auto i =3D a.begin() + (ci - a.begin());
>> >>> For a list: auto i =3D a.erase(ci, ci); // This is only guaranteed t=
o be
>> >>> O(n) for a std::vector, although in most implementations this will b=
e
>> O(1)
>> >>>
>> >>
>> >> Isn't N=3D=3D1 in the latter? Seems to me that erase(ci, ci) does wha=
t you
>> >> want on every container I can find.
>> >
>> > Well, actually, erase(ci, ci) will return an iterator that'll point to
>> ci+1,
>> > so an additional operator-- is needed.
>>
>> IMO, we shouldn't teach people to use tricky combinations of library
>> functionality to realize a well-defined coding pattern. C++11
>> respected that many iterator arguments that are part of some API
>> function are pure position specifiers. The access function suggested
>> above allows more than that, but it is still const-correct in all
>> respects, so I do disagree with Nicol that this is similar to a
>> const_cast. The presented workarounds (which look ugly to me and I
>> don't consider them as acceptable ones), just demonstrate that if I
>> have a non-const container I do have full access to what the interface
>> allows me to do - including "computing" the non-const iterator of a
>> given const_iterator. The access function would still be right for
>> sets, which are basically immutable, albeit of little advantage, but
>> IMO reasonable for symmetry reasons.
>>
>> My personal recommendation would be to change the name, though,
>> because "access" sounds too generic to me. I remember that during some
>> committee meeting someone suggested a name along the side of
>> "to_iterator". I might even make sense to make this a free function
>> and allow ADL to find the right one, so we can use the same code
>> pattern for built-in arrays as well.
>>
>>
>>
> 200% agreed. to_iterator() sounds fine to me. Let the bike-shedding begin=
..
> :)
> Want to co-author an LEWG paper? The target would likely be a library TS
> and c++17 after that, I have no interest in pushing this into c++14.
>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--047d7b3a89764d245304e4b4bf4e
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>to_iterator indeed sounds a lot better. :)<br><br></d=
iv>I'm sorry, but what does TS mean in 'library TS'? I don'=
t recognize the acronym. (I'm quite new to C++ standardization.)<br></d=
iv>
<div class=3D"gmail_extra"><br><br><div class=3D"gmail_quote">2013/8/24 Vil=
le Voutilainen <span dir=3D"ltr"><<a href=3D"mailto:ville.voutilainen@gm=
ail.com" target=3D"_blank">ville.voutilainen@gmail.com</a>></span><br><b=
lockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px =
#ccc solid;padding-left:1ex">
<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><br><div class=3D"gmail=
_quote"><div><div class=3D"h5">On 24 August 2013 17:41, Daniel Kr=FCgler <s=
pan dir=3D"ltr"><<a href=3D"mailto:daniel.kruegler@gmail.com" target=3D"=
_blank">daniel.kruegler@gmail.com</a>></span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">2013/8/24 Ville Voutilainen <<a href=3D"m=
ailto:ville.voutilainen@gmail.com" target=3D"_blank">ville.voutilainen@gmai=
l.com</a>>:<br>
<div><div>><br>
> On 24 August 2013 16:34, Ville Voutilainen <<a href=3D"mailto:ville=
..voutilainen@gmail.com" target=3D"_blank">ville.voutilainen@gmail.com</a>&g=
t;<br>
> wrote:<br>
>><br>
>><br>
>> On 24 August 2013 14:39, Maurice Bos <<a href=3D"mailto:m-ou.se=
@m-ou.se" target=3D"_blank">m-ou.se@m-ou.se</a>> wrote:<br>
>>><br>
>>> Hello,<br>
>>><br>
>>> Since C++11, a lot of member functions of containers that used=
to take<br>
>>> (non-const) iterators, now take const_iterators (such as inser=
t, erase,<br>
>>> etc.), since those member functions can only be called on non-=
const<br>
>>> containers anyway and can thus modify it.<br>
>>><br>
>>> However, what seems to be missing is to get a (non-const) iter=
ator, given<br>
>>> a non-const (reference to) a constainer and a const_iterator i=
n it. For<br>
>>> example:<br>
>>><br>
>>> vector<int> a;<br>
>>> vector<int>::const_iterator ci =3D a.cbegin();<br>
>>> vector<int>::iterator i =3D a.access(ci); // turn it int=
o a non-const<br>
>>> iterator.<br>
>>><br>
>>> Although this is already possible, there is currently no cross=
-container<br>
>>> way do this in O(1):<br>
>>><br>
>>> For a vector: auto i =3D a.begin() + (ci - a.begin());<br>
>>> For a list: auto i =3D a.erase(ci, ci); // This is only guaran=
teed to be<br>
>>> O(n) for a std::vector, although in most implementations this =
will be O(1)<br>
>>><br>
>><br>
>> Isn't N=3D=3D1 in the latter? Seems to me that erase(ci, ci) d=
oes what you<br>
>> want on every container I can find.<br>
><br>
> Well, actually, erase(ci, ci) will return an iterator that'll poin=
t to ci+1,<br>
> so an additional operator-- is needed.<br>
<br>
</div></div>IMO, we shouldn't teach people to use tricky combinations o=
f library<br>
functionality to realize a well-defined coding pattern. C++11<br>
respected that many iterator arguments that are part of some API<br>
function are pure position specifiers. The access function suggested<br>
above allows more than that, but it is still const-correct in all<br>
respects, so I do disagree with Nicol that this is similar to a<br>
const_cast. The presented workarounds (which look ugly to me and I<br>
don't consider them as acceptable ones), just demonstrate that if I<br>
have a non-const container I do have full access to what the interface<br>
allows me to do - including "computing" the non-const iterator of=
a<br>
given const_iterator. The access function would still be right for<br>
sets, which are basically immutable, albeit of little advantage, but<br>
IMO reasonable for symmetry reasons.<br>
<br>
My personal recommendation would be to change the name, though,<br>
because "access" sounds too generic to me. I remember that during=
some<br>
committee meeting someone suggested a name along the side of<br>
"to_iterator". I might even make sense to make this a free functi=
on<br>
and allow ADL to find the right one, so we can use the same code<br>
pattern for built-in arrays as well.<br>
<span><font color=3D"#888888"><br><br></font></span></blockquote><div><br><=
/div></div></div><div>200% agreed. to_iterator() sounds fine to me. Let the=
bike-shedding begin. :)<br></div><div>Want to co-author an LEWG paper? The=
target would likely be a library TS<br>
and c++17 after that, I have no interest in pushing this into c++14. <br></=
div></div><br></div></div><div class=3D"HOEnZb"><div class=3D"h5">
<p></p>
-- <br>
=A0<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org" target=3D=
"_blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--047d7b3a89764d245304e4b4bf4e--
.
Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Sat, 24 Aug 2013 10:55:51 -0700 (PDT)
Raw View
------=_Part_150_20158902.1377366951719
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
How about unconst(). to_iterator is still somewhat vague, when it comes to=
=20
what it is useful for.
I would have guessed that to_iterator woudl take an index and return=20
"begin() + index".
Den l=F6rdagen den 24:e augusti 2013 kl. 13:39:57 UTC+2 skrev Maurice Bos:
>
> Hello,
>
> Since C++11, a lot of member functions of containers that used to take=20
> (non-const) iterators, now take const_iterators (such as insert, erase,=
=20
> etc.), since those member functions can only be called on non-const=20
> containers anyway and can thus modify it.
>
> However, what seems to be missing is to get a (non-const) iterator, given=
=20
> a non-const (reference to) a constainer and a const_iterator in it. For=
=20
> example:
>
> vector<int> a;
> vector<int>::const_iterator ci =3D a.cbegin();
> vector<int>::iterator i =3D a.access(ci); // turn it into a non-const=20
> iterator.
>
> Although this is already possible, there is currently no cross-container=
=20
> way do this in O(1):
>
> For a vector: auto i =3D a.begin() + (ci - a.begin());
> For a list: auto i =3D a.erase(ci, ci); // This is only guaranteed to be=
=20
> O(n) for a std::vector, although in most implementations this will be O(1=
)
>
> I needed this when i was making a class template called 'vectorset', whic=
h=20
> has the interface of a std set, but keeps its contents in a vector (or=20
> list, or deque, or anything else with a vector-like interface, depending =
on=20
> a template parameter). (It has less efficient inserting and erasing=20
> obviously, but it's more memory efficient and probably a better choice fo=
r,=20
> for example, a (mostly) constant set of just a few integers.) To make the=
=20
> insert member function take a const_iterator as hint, i needed to convert=
=20
> it to a non-const iterator, which can currently not be done in one way=20
> that's O(1) for all containers.
>
> Has anybody else encountered such a situation? Any arguments against=20
> adding this funcitonality?
>
> Kind regards,
> Maurice Bos
>
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_150_20158902.1377366951719
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">How about unconst(). to_iterator is still somewhat vague, =
when it comes to what it is useful for.<div><br></div><div>I would have gue=
ssed that to_iterator woudl take an index and return "begin() + index".<br>=
<br>Den l=F6rdagen den 24:e augusti 2013 kl. 13:39:57 UTC+2 skrev Maurice B=
os:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;=
border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>Hello=
,<br><br>Since C++11, a lot of member functions of containers that used to =
take (non-const) iterators, now take const_iterators (such as insert, erase=
, etc.), since those member functions can only be called on non-const conta=
iners anyway and can thus modify it.<br>
<br>However, what seems to be missing is to get a (non-const) iterator, giv=
en a non-const (reference to) a constainer and a const_iterator in it. For =
example:<br><br>vector<int> a;<br></div>vector<int>::const_iter=
ator ci =3D a.cbegin();<br>
vector<int>::iterator i =3D a.access(ci); // turn it into a non-const=
iterator.<br><br>Although this is already possible, there is currently no =
cross-container way do this in O(1):<br><br>For a vector: auto i =3D a.begi=
n() + (ci - a.begin());<br>
For a list: auto i =3D a.erase(ci, ci); // This is only guaranteed to be O(=
n) for a std::vector, although in most implementations this will be O(1)<br=
><br>I needed this when i was making a class template called 'vectorset', w=
hich has the interface of a std set, but keeps its contents in a vector (or=
list, or deque, or anything else with a vector-like interface, depending o=
n a template parameter). (It has less efficient inserting and erasing obvio=
usly, but it's more memory efficient and probably a better choice for, for =
example, a (mostly) constant set of just a few integers.) To make the inser=
t member function take a const_iterator as hint, i needed to convert it to =
a non-const iterator, which can currently not be done in one way that's O(1=
) for all containers.<br>
<br>Has anybody else encountered such a situation? Any arguments against ad=
ding this funcitonality?<br><br>Kind regards,<br>Maurice Bos<br></div>
</blockquote></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_150_20158902.1377366951719--
.
Author: Christof Meerwald <cmeerw@cmeerw.org>
Date: Sat, 24 Aug 2013 20:07:57 +0200
Raw View
On Sat, Aug 24, 2013 at 07:20:41PM +0200, Maurice Bos wrote:
> I'm sorry, but what does TS mean in 'library TS'? I don't recognize the
> acronym. (I'm quite new to C++ standardization.)
Technical Specification, see
http://isocpp.org/std/iso-iec-jtc1-procedures
Christof
--
http://cmeerw.org sip:cmeerw at cmeerw.org
mailto:cmeerw at cmeerw.org xmpp:cmeerw at cmeerw.org
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sat, 24 Aug 2013 17:56:14 -0700 (PDT)
Raw View
------=_Part_43_26132609.1377392174259
Content-Type: text/plain; charset=ISO-8859-1
On Saturday, August 24, 2013 10:08:17 AM UTC-7, Maurice Bos wrote:
>
>
> 2013/8/24 Nicol Bolas <jmck...@gmail.com <javascript:>>
>
>>
>> Um, no. That's like saying you have a `const &` to something and you want
>> a non-`const` reference to it. Yes, there's a way to do it, but you should
>> pretty much never employ it. If you were meant to have modifiable access to
>> the container, you wouldn't have been given a const_iterator to begin with.
>>
>
> No, modifying functions like insert and erase take a const_iterator. So
> "If you were meant to have modifiable access to the container, you wouldn't
> have been given a const_iterator to begin with." is invalid.
>
But you're *not* modifying the item referenced by the iterator. You're
modifying the *container*; the iterator is just a *hint* about where the
data should go. That's why set::insert is not *const*.
Why do you need to convert it to a non-const iterator? std::set::insert
>> only takes an iterator as a hint. If you're implementing a flat_set (which
>> BTW, Boost has already done for you<http://www.boost.org/doc/libs/1_54_0/doc/html/container/non_standard_containers.html#container.non_standard_containers.flat_xxx>),
>> you should use it to tell you the position in the array for where to start
>> looking. You don't need this position to be modifiable. You can convert it
>> into an array index easily enough, for example.
>>
>
> "You can convert it into an array index easily enough"... Well, no, that's
> my point. For arrays/vectors, yes, but you can't get do it in O(1) in a way
> that works for all containers...
>
But that's irrelevant for your case, since your flat_set is using a
std::vector for the array. Which is rather the point.
Unless you want to allow people to use std::list (which would be *utterly*idiotic. They should just use std::set) or arbitrary other containers. And
if you do, see below.
Or better yet, you can do whatever you want. It is, after all, *your*iterator; you can convert it into a non-const pointer to the array element
>> if you like. It can have whatever private interface on it you like. You are
>> not restricted to the same interface that you permit others to have.
>>
>
> No, it isn't *my* iterator. The vectorset/flat_set/whatever just can just
> use the iterators of the underlying container. It are vector/list/deque's
> iterators, not 'my' iterators.
>
Every programming problem can be solved by adding an additional layer of
indirection. And this is no exception. So if, for whatever reason, you
don't know that you're using a vector, you can simply create a wrapper
iterator class that *contains* the underlying iterator. Your const_iterator
could contain a non-const internal iterator.
Most people don't need to perform a const_cast on iterators, and I would go
so far as to say that if you have written code where you need to, you're
doing it wrong.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_43_26132609.1377392174259
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Saturday, August 24, 2013 10:08:17 AM UTC-7, Maurice Bo=
s wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0=
..8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><br><=
div><div class=3D"gmail_quote">2013/8/24 Nicol Bolas <span dir=3D"ltr"><=
<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"rIYP3qic=
ymwJ">jmck...@gmail.com</a>></span><br><blockquote class=3D"gmail_quote"=
style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);p=
adding-left:1ex">
<div dir=3D"ltr"><div><br>Um, no. That's like saying you have a `const &=
;` to something and you want a non-`const` reference to it. Yes, there's a =
way to do it, but you should pretty much never employ it. If you were meant=
to have modifiable access to the container, you wouldn't have been given a=
const_iterator to begin with.<br>
</div></div></blockquote><div><br>No, modifying functions like insert and e=
rase take a const_iterator. So "If you were meant to have modifiable access=
to the container, you wouldn't have been given a const_iterator to begin w=
ith." is invalid.</div></div></div></div></blockquote><div><br>But you're <=
i>not</i> modifying the item referenced by the iterator. You're modifying t=
he <i>container</i>; the iterator is just a <i>hint</i> about where the dat=
a should go. That's why set::insert is not <i>const</i>.<br><br></div><bloc=
kquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-l=
eft: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=3D=
"gmail_quote"><div>
</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;b=
order-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><d=
iv>Why do you need to convert it to a non-const iterator? std::set::insert =
only takes an iterator as a hint. If you're implementing a flat_set (which =
BTW, <a href=3D"http://www.boost.org/doc/libs/1_54_0/doc/html/container/non=
_standard_containers.html#container.non_standard_containers.flat_xxx" targe=
t=3D"_blank">Boost has already done for you</a>), you should use it to tell=
you the position in the array for where to start looking. You don't need t=
his position to be modifiable. You can convert it into an array index easil=
y enough, for example.<br>
</div></div></blockquote><div><br>"You can convert it into an array index e=
asily enough"... Well, no, that's my point. For arrays/vectors, yes, but yo=
u can't get do it in O(1) in a way that works for all containers...<br></di=
v></div></div></div></blockquote><div><br>But that's irrelevant for your ca=
se, since your flat_set is using a std::vector for the array. Which is rath=
er the point.<br><br>Unless you want to allow people to use std::list (whic=
h would be <i>utterly</i> idiotic. They should just use std::set) or arbitr=
ary other containers. And if you do, see below.<br><br></div><blockquote cl=
ass=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px =
#ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=3D"gmail_qu=
ote"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;bo=
rder-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><di=
v>
Or better yet, you can do whatever you want. It is, after all, <i>your</i> =
iterator; you can convert it into a non-const pointer to the array element =
if you like. It can have whatever private interface on it you like. You are=
not restricted to the same interface that you permit others to have.<br>
</div></div></blockquote><div><br>No, it isn't *my* iterator. The vectorset=
/flat_set/whatever just can just use the iterators of the underlying contai=
ner. It are vector/list/deque's iterators, not 'my' iterators.<br></div></d=
iv></div></div></blockquote><div><br>Every programming problem can be solve=
d by adding an additional layer of indirection. And this is no exception. S=
o if, for whatever reason, you don't know that you're using a vector, you c=
an simply create a wrapper iterator class that <i>contains</i> the underlyi=
ng iterator. Your const_iterator could contain a non-const internal iterato=
r.<br><br>Most people don't need to perform a const_cast on iterators, and =
I would go so far as to say that if you have written code where you need to=
, you're doing it wrong.<br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_43_26132609.1377392174259--
.
Author: Maurice Bos <m-ou.se@m-ou.se>
Date: Sun, 25 Aug 2013 11:53:19 +0200
Raw View
--089e01493e423d652104e4c29dd1
Content-Type: text/plain; charset=ISO-8859-1
2013/8/25 Nicol Bolas <jmckesson@gmail.com>
> On Saturday, August 24, 2013 10:08:17 AM UTC-7, Maurice Bos wrote:
>>
>>
>> 2013/8/24 Nicol Bolas <jmck...@gmail.com>
>>
>>
>>> Um, no. That's like saying you have a `const &` to something and you
>>> want a non-`const` reference to it. Yes, there's a way to do it, but you
>>> should pretty much never employ it. If you were meant to have modifiable
>>> access to the container, you wouldn't have been given a const_iterator to
>>> begin with.
>>>
>>
>> No, modifying functions like insert and erase take a const_iterator. So
>> "If you were meant to have modifiable access to the container, you wouldn't
>> have been given a const_iterator to begin with." is invalid.
>>
>
> But you're *not* modifying the item referenced by the iterator. You're
> modifying the *container*; the iterator is just a *hint* about where the
> data should go. That's why set::insert is not *const*.
>
Sure, but I can't modify the container at the point the hint points to,
without a dirty trick as erasing an empty range at the hint, or iterating
distance(begin, hint) from begin. Depending on how you implement the
flat_set, it might not be needed since you can pass the problem on to the
insert/erase functions of the underlying container. However, imagine
another container wrapper that only gives the user const access to the
elements (simply through const_iterators of the underlying container), and
only allows modification through member functions. Those member functions
should take a const_iterator to point to which element needs to be changed.
Those member functions somehow need to modify the element the
const_iterator pointed to. (Which is still const-correct, because the
member functions have non-const access to the container.) (This to make
sure that only the 'wrapper' class, and not anybody else, can modify the
underlying container.)
Or think of a function 'foobar' that, like std::upper_bound, looks up a
position inside a range. Since the function does not modify the container,
but only gives you a position depending on the values in the range, it
should just take const_iterators and return a const_iterator. However, if
const_iterators aren't convertible to iterators when you have non-const
access to the container, a function having the (non-const) container can't
use foobar to look up an element in the container and then change that
element. For that, another overload of 'foobar' needs to be made that works
on non-const iterators, which would suggest 'foobar' modifies the elements
the iterators point to, which is not the case. (So adding this to_iterator
functionality will actually improve const-correctness in this case.)
>
> Why do you need to convert it to a non-const iterator? std::set::insert
>>> only takes an iterator as a hint. If you're implementing a flat_set (which
>>> BTW, Boost has already done for you<http://www.boost.org/doc/libs/1_54_0/doc/html/container/non_standard_containers.html#container.non_standard_containers.flat_xxx>),
>>> you should use it to tell you the position in the array for where to start
>>> looking. You don't need this position to be modifiable. You can convert it
>>> into an array index easily enough, for example.
>>>
>>
>> "You can convert it into an array index easily enough"... Well, no,
>> that's my point. For arrays/vectors, yes, but you can't get do it in O(1)
>> in a way that works for all containers...
>>
>
> But that's irrelevant for your case, since your flat_set is using a
> std::vector for the array. Which is rather the point.
>
Eh, no. It could use any sequence container. I agree that std::list would
not be useful in this case, but std::deque might. Also, any other container
anybody implemented outside std::, or any containers that will be added
later to the standard, might also have useful properties for this purpose.
(Such as boost::static_vector.)
>
> Unless you want to allow people to use std::list (which would be *utterly*idiotic. They should just use std::set) or arbitrary other containers. And
> if you do, see below.
>
> Or better yet, you can do whatever you want. It is, after all, *your*iterator; you can convert it into a non-const pointer to the array element
>>> if you like. It can have whatever private interface on it you like. You are
>>> not restricted to the same interface that you permit others to have.
>>>
>>
>> No, it isn't *my* iterator. The vectorset/flat_set/whatever just can just
>> use the iterators of the underlying container. It are vector/list/deque's
>> iterators, not 'my' iterators.
>>
>
> Every programming problem can be solved by adding an additional layer of
> indirection. And this is no exception. So if, for whatever reason, you
> don't know that you're using a vector, you can simply create a wrapper
> iterator class that *contains* the underlying iterator. Your
> const_iterator could contain a non-const internal iterator.
>
So you prefer adding a whole other layer of indirection over just giving
functionality that is already there (.erase(i,i)) a proper name (and making
it O(1))?
>
> Most people don't need to perform a const_cast on iterators, and I would
> go so far as to say that if you have written code where you need to, you're
> doing it wrong.
>
Like Daniel already said, it is perfectly const-correct. It is nothing like
a const_cast. If it weren't const-correct, erase wouldn't turn its second
parameter (a const_iterator) into an iterator.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--089e01493e423d652104e4c29dd1
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><br><div class=3D"gmail=
_quote">2013/8/25 Nicol Bolas <span dir=3D"ltr"><<a href=3D"mailto:jmcke=
sson@gmail.com" target=3D"_blank">jmckesson@gmail.com</a>></span><br><bl=
ockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #=
ccc solid;padding-left:1ex">
<div dir=3D"ltr">On Saturday, August 24, 2013 10:08:17 AM UTC-7, Maurice Bo=
s wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br><div><=
div class=3D"gmail_quote">
2013/8/24 Nicol Bolas <span dir=3D"ltr"><<a>jmck...@gmail.com</a>></s=
pan><div><br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px =
0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div dir=3D"ltr"><div><br>Um, no. That's like saying you have a `const =
&` to something and you want a non-`const` reference to it. Yes, there&=
#39;s a way to do it, but you should pretty much never employ it. If you we=
re meant to have modifiable access to the container, you wouldn't have =
been given a const_iterator to begin with.<br>
</div></div></blockquote><div><br>No, modifying functions like insert and e=
rase take a const_iterator. So "If you were meant to have modifiable a=
ccess to the container, you wouldn't have been given a const_iterator t=
o begin with." is invalid.</div>
</div></div></div></div></blockquote><div><br>But you're <i>not</i> mod=
ifying the item referenced by the iterator. You're modifying the <i>con=
tainer</i>; the iterator is just a <i>hint</i> about where the data should =
go. That's why set::insert is not <i>const</i>.<br>
</div></div></blockquote><div><br>Sure, but I can't modify the containe=
r at the point the hint points to, without a dirty trick as erasing an empt=
y range at the hint, or iterating distance(begin, hint) from begin. Dependi=
ng on how you implement the flat_set, it might not be needed since you can =
pass the problem on to the insert/erase functions of the underlying contain=
er. However, imagine another container wrapper that only gives the user con=
st access to the elements (simply through const_iterators of the underlying=
container), and only allows modification through member functions. Those m=
ember functions should take a const_iterator to point to which element need=
s to be changed. Those member functions somehow need to modify the element =
the const_iterator pointed to. (Which is still const-correct, because the m=
ember functions have non-const access to the container.) (This to make sure=
that only the 'wrapper' class, and not anybody else, can modify th=
e underlying container.)<br>
<br>Or think of a function 'foobar' that, like std::upper_bound, lo=
oks up a position inside a range. Since the function does not modify the co=
ntainer, but only gives you a position depending on the values in the range=
, it should just take const_iterators and return a const_iterator. However,=
if const_iterators aren't convertible to iterators when you have non-c=
onst access to the container, a function having the (non-const) container c=
an't use foobar to look up an element in the container and then change =
that element. For that, another overload of 'foobar' needs to be ma=
de that works on non-const iterators, which would suggest 'foobar' =
modifies the elements the iterators point to, which is not the case. (So ad=
ding this to_iterator functionality will actually improve const-correctness=
in this case.)<br>
=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;borde=
r-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><br></div><di=
v><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bor=
der-left:1px #ccc solid;padding-left:1ex">
<div dir=3D"ltr"><div><div class=3D"gmail_quote"><div>
</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;b=
order-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><d=
iv>Why do you need to convert it to a non-const iterator? std::set::insert =
only takes an iterator as a hint. If you're implementing a flat_set (wh=
ich BTW, <a href=3D"http://www.boost.org/doc/libs/1_54_0/doc/html/container=
/non_standard_containers.html#container.non_standard_containers.flat_xxx" t=
arget=3D"_blank">Boost has already done for you</a>), you should use it to =
tell you the position in the array for where to start looking. You don'=
t need this position to be modifiable. You can convert it into an array ind=
ex easily enough, for example.<br>
</div></div></blockquote><div><br>"You can convert it into an array in=
dex easily enough"... Well, no, that's my point. For arrays/vector=
s, yes, but you can't get do it in O(1) in a way that works for all con=
tainers...<br>
</div></div></div></div></blockquote></div><div><br>But that's irreleva=
nt for your case, since your flat_set is using a std::vector for the array.=
Which is rather the point.<br></div></div></blockquote><div><br></div>
<div>Eh, no. It could use any sequence container. I agree that std::list wo=
uld not be useful in this case, but std::deque might. Also, any other conta=
iner anybody implemented outside std::, or any containers that will be adde=
d later to the standard, might also have useful properties for this purpose=
.. (Such as boost::static_vector.)<br>
</div><div>=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0=
.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><b=
r>Unless you want to allow people to use std::list (which would be <i>utter=
ly</i> idiotic. They should just use std::set) or arbitrary other container=
s. And if you do, see below.<br>
<br></div><div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-l=
eft:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><di=
v><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1=
ex">
<div dir=3D"ltr"><div>
Or better yet, you can do whatever you want. It is, after all, <i>your</i> =
iterator; you can convert it into a non-const pointer to the array element =
if you like. It can have whatever private interface on it you like. You are=
not restricted to the same interface that you permit others to have.<br>
</div></div></blockquote><div><br>No, it isn't *my* iterator. The vecto=
rset/flat_set/whatever just can just use the iterators of the underlying co=
ntainer. It are vector/list/deque's iterators, not 'my' iterato=
rs.<br>
</div></div></div></div></blockquote></div><div><br>Every programming probl=
em can be solved by adding an additional layer of indirection. And this is =
no exception. So if, for whatever reason, you don't know that you'r=
e using a vector, you can simply create a wrapper iterator class that <i>co=
ntains</i> the underlying iterator. Your const_iterator could contain a non=
-const internal iterator.<br>
</div></div></blockquote><div><br>So you prefer adding a whole other layer =
of indirection over just giving functionality that is already there (.erase=
(i,i)) a proper name (and making it O(1))?<br>=A0</div><blockquote class=3D=
"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding=
-left:1ex">
<div dir=3D"ltr"><div><br>Most people don't need to perform a const_cas=
t on iterators, and I would go so far as to say that if you have written co=
de where you need to, you're doing it wrong.<br></div></div></blockquot=
e>
<div><br>Like Daniel already said, it is perfectly const-correct. It is not=
hing like a const_cast. If it weren't const-correct, erase wouldn't=
turn its second parameter (a const_iterator) into an iterator.<br></div>
</div></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--089e01493e423d652104e4c29dd1--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sun, 25 Aug 2013 03:29:36 -0700 (PDT)
Raw View
------=_Part_913_30189968.1377426576833
Content-Type: text/plain; charset=ISO-8859-1
On Sunday, August 25, 2013 2:53:19 AM UTC-7, Maurice Bos wrote:
>
> 2013/8/25 Nicol Bolas <jmck...@gmail.com <javascript:>>
>
>> On Saturday, August 24, 2013 10:08:17 AM UTC-7, Maurice Bos wrote:
>>>
>>>
>>> 2013/8/24 Nicol Bolas <jmck...@gmail.com>
>>>
>>>
>>>> Um, no. That's like saying you have a `const &` to something and you
>>>> want a non-`const` reference to it. Yes, there's a way to do it, but you
>>>> should pretty much never employ it. If you were meant to have modifiable
>>>> access to the container, you wouldn't have been given a const_iterator to
>>>> begin with.
>>>>
>>>
>>> No, modifying functions like insert and erase take a const_iterator. So
>>> "If you were meant to have modifiable access to the container, you wouldn't
>>> have been given a const_iterator to begin with." is invalid.
>>>
>>
>> But you're *not* modifying the item referenced by the iterator. You're
>> modifying the *container*; the iterator is just a *hint* about where the
>> data should go. That's why set::insert is not *const*.
>>
>
> Sure, but I can't modify the container at the point the hint points to,
> without a dirty trick as erasing an empty range at the hint, or iterating
> distance(begin, hint) from begin. Depending on how you implement the
> flat_set, it might not be needed since you can pass the problem on to the
> insert/erase functions of the underlying container. However, imagine
> another container wrapper that only gives the user const access to the
> elements (simply through const_iterators of the underlying container), and
> only allows modification through member functions. Those member functions
> should take a const_iterator to point to which element needs to be changed.
> Those member functions somehow need to modify the element the
> const_iterator pointed to. (Which is still const-correct, because the
> member functions have non-const access to the container.) (This to make
> sure that only the 'wrapper' class, and not anybody else, can modify the
> underlying container.)
>
> Or think of a function 'foobar' that, like std::upper_bound, looks up a
> position inside a range. Since the function does not modify the container,
> but only gives you a position depending on the values in the range, it
> should just take const_iterators and return a const_iterator. However, if
> const_iterators aren't convertible to iterators when you have non-const
> access to the container, a function having the (non-const) container can't
> use foobar to look up an element in the container and then change that
> element.
>
That doesn't make sense. If you give a function a const_iterator, the whole
point of doing that is so that it *can't* modify the data referenced
through that iterator. So if the calling function needs to modify an
element, then the calling function will not be using const_iterators. It's
really that simple.
There's a reason std::upper_bound is templated on the iterator type.
If you want to modify what comes out of std::upper_bound, then you don't
pass it const_iterators. Just like you wouldn't pass it const pointers if
you want to modify the data pointed to by the return value.
For that, another overload of 'foobar' needs to be made that works on
> non-const iterators, which would suggest 'foobar' modifies the elements the
> iterators point to, which is not the case. (So adding this to_iterator
> functionality will actually improve const-correctness in this case.)
>
Or you have a template `foobar` that works with what you give it. Just like
std::upper_bound. There's no reason someone should be restricted from
passing pointers or other iterator-like things.
>> Why do you need to convert it to a non-const iterator? std::set::insert
>>>> only takes an iterator as a hint. If you're implementing a flat_set (which
>>>> BTW, Boost has already done for you<http://www.boost.org/doc/libs/1_54_0/doc/html/container/non_standard_containers.html#container.non_standard_containers.flat_xxx>),
>>>> you should use it to tell you the position in the array for where to start
>>>> looking. You don't need this position to be modifiable. You can convert it
>>>> into an array index easily enough, for example.
>>>>
>>>
>>> "You can convert it into an array index easily enough"... Well, no,
>>> that's my point. For arrays/vectors, yes, but you can't get do it in O(1)
>>> in a way that works for all containers...
>>>
>>
>> But that's irrelevant for your case, since your flat_set is using a
>> std::vector for the array. Which is rather the point.
>>
>
> Eh, no. It could use any sequence container. I agree that std::list would
> not be useful in this case, but std::deque might. Also, any other container
> anybody implemented outside std::, or any containers that will be added
> later to the standard, might also have useful properties for this purpose.
> (Such as boost::static_vector.)
>
Are you making a container, or a container *adapter* like std::stack and
std::queue? Because those are completely different things with very
different expectations.
There's a reason std::flat_set doesn't have a parameter for the internal
container. That's because, if it uses an internal container at all, it's
just an implementation detail.
Or better yet, you can do whatever you want. It is, after all, *your*iterator; you can convert it into a non-const pointer to the array element
>>>> if you like. It can have whatever private interface on it you like. You are
>>>> not restricted to the same interface that you permit others to have.
>>>>
>>>
>>> No, it isn't *my* iterator. The vectorset/flat_set/whatever just can
>>> just use the iterators of the underlying container. It are
>>> vector/list/deque's iterators, not 'my' iterators.
>>>
>>
>> Every programming problem can be solved by adding an additional layer of
>> indirection. And this is no exception. So if, for whatever reason, you
>> don't know that you're using a vector, you can simply create a wrapper
>> iterator class that *contains* the underlying iterator. Your
>> const_iterator could contain a non-const internal iterator.
>>
>
> So you prefer adding a whole other layer of indirection over just giving
> functionality that is already there (.erase(i,i)) a proper name (and making
> it O(1))?
>
vector::erase only does that as a *side effect*, not its intended purpose.
Indeed, I'd rather that this was fixed in vector::erase, so that passing
the same iterator will fail or something.
>> Most people don't need to perform a const_cast on iterators, and I would
>> go so far as to say that if you have written code where you need to, you're
>> doing it wrong.
>>
>
> Like Daniel already said, it is perfectly const-correct. It is nothing
> like a const_cast. If it weren't const-correct, erase wouldn't turn its
> second parameter (a const_iterator) into an iterator.
>
It doesn't "turn its second parameter" into anything. It *creates a new
iterator*, since after the erasure, the old iterator may be invalid. See
the difference? It's not converting anything.
It's const-correct because the container itself must be non-const to do
that. And that means that the container can *generate* whatever non-const
iterator it wants.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_913_30189968.1377426576833
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Sunday, August 25, 2013 2:53:19 AM UTC-7, Maurice Bos w=
rote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8e=
x;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><di=
v class=3D"gmail_quote">2013/8/25 Nicol Bolas <span dir=3D"ltr"><<a href=
=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"rGSGT59jxEkJ">j=
mck...@gmail.com</a>></span><br><blockquote class=3D"gmail_quote" style=
=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir=3D"ltr">On Saturday, August 24, 2013 10:08:17 AM UTC-7, Maurice Bo=
s wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br><div><=
div class=3D"gmail_quote">
2013/8/24 Nicol Bolas <span dir=3D"ltr"><<a>jmck...@gmail.com</a>></s=
pan><div><br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px =
0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div dir=3D"ltr"><div><br>Um, no. That's like saying you have a `const &=
;` to something and you want a non-`const` reference to it. Yes, there's a =
way to do it, but you should pretty much never employ it. If you were meant=
to have modifiable access to the container, you wouldn't have been given a=
const_iterator to begin with.<br>
</div></div></blockquote><div><br>No, modifying functions like insert and e=
rase take a const_iterator. So "If you were meant to have modifiable access=
to the container, you wouldn't have been given a const_iterator to begin w=
ith." is invalid.</div>
</div></div></div></div></blockquote><div><br>But you're <i>not</i> modifyi=
ng the item referenced by the iterator. You're modifying the <i>container</=
i>; the iterator is just a <i>hint</i> about where the data should go. That=
's why set::insert is not <i>const</i>.<br>
</div></div></blockquote><div><br>Sure, but I can't modify the container at=
the point the hint points to, without a dirty trick as erasing an empty ra=
nge at the hint, or iterating distance(begin, hint) from begin. Depending o=
n how you implement the flat_set, it might not be needed since you can pass=
the problem on to the insert/erase functions of the underlying container. =
However, imagine another container wrapper that only gives the user const a=
ccess to the elements (simply through const_iterators of the underlying con=
tainer), and only allows modification through member functions. Those membe=
r functions should take a const_iterator to point to which element needs to=
be changed. Those member functions somehow need to modify the element the =
const_iterator pointed to. (Which is still const-correct, because the membe=
r functions have non-const access to the container.) (This to make sure tha=
t only the 'wrapper' class, and not anybody else, can modify the underlying=
container.)<br>
<br>Or think of a function 'foobar' that, like std::upper_bound, looks up a=
position inside a range. Since the function does not modify the container,=
but only gives you a position depending on the values in the range, it sho=
uld just take const_iterators and return a const_iterator. However, if cons=
t_iterators aren't convertible to iterators when you have non-const access =
to the container, a function having the (non-const) container can't use foo=
bar to look up an element in the container and then change that element.</d=
iv></div></div></div></blockquote><div><br>That doesn't make sense. If you =
give a function a const_iterator, the whole point of doing that is so that =
it <i>can't</i> modify the data referenced through that iterator. So if the=
calling function needs to modify an element, then the calling function wil=
l not be using const_iterators. It's really that simple.<br><br>There's a r=
eason std::upper_bound is templated on the iterator type.<br><br>If you wan=
t to modify what comes out of std::upper_bound, then you don't pass it cons=
t_iterators. Just like you wouldn't pass it const pointers if you want to m=
odify the data pointed to by the return value.<br><br></div><blockquote cla=
ss=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #=
ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=3D"gmail_quo=
te"><div> For that, another overload of 'foobar' needs to be made that work=
s on non-const iterators, which would suggest 'foobar' modifies the element=
s the iterators point to, which is not the case. (So adding this to_iterato=
r functionality will actually improve const-correctness in this case.)<br><=
/div></div></div></div></blockquote><div><br>Or you have a template `foobar=
` that works with what you give it. Just like std::upper_bound. There's no =
reason someone should be restricted from passing pointers or other iterator=
-like things.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><di=
v dir=3D"ltr"><div><div class=3D"gmail_quote"><div>
</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-l=
eft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><br></div><div><=
blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border=
-left:1px #ccc solid;padding-left:1ex">
<div dir=3D"ltr"><div><div class=3D"gmail_quote"><div>
</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;b=
order-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><d=
iv>Why do you need to convert it to a non-const iterator? std::set::insert =
only takes an iterator as a hint. If you're implementing a flat_set (which =
BTW, <a href=3D"http://www.boost.org/doc/libs/1_54_0/doc/html/container/non=
_standard_containers.html#container.non_standard_containers.flat_xxx" targe=
t=3D"_blank">Boost has already done for you</a>), you should use it to tell=
you the position in the array for where to start looking. You don't need t=
his position to be modifiable. You can convert it into an array index easil=
y enough, for example.<br>
</div></div></blockquote><div><br>"You can convert it into an array index e=
asily enough"... Well, no, that's my point. For arrays/vectors, yes, but yo=
u can't get do it in O(1) in a way that works for all containers...<br>
</div></div></div></div></blockquote></div><div><br>But that's irrelevant f=
or your case, since your flat_set is using a std::vector for the array. Whi=
ch is rather the point.<br></div></div></blockquote><div><br></div>
<div>Eh, no. It could use any sequence container. I agree that std::list wo=
uld not be useful in this case, but std::deque might. Also, any other conta=
iner anybody implemented outside std::, or any containers that will be adde=
d later to the standard, might also have useful properties for this purpose=
.. (Such as boost::static_vector.)<br></div></div></div></div></blockquote><=
div><br>Are you making a container, or a container <i>adapter</i> like std:=
:stack and std::queue? Because those are completely different things with v=
ery different expectations.<br><br>There's a reason std::flat_set doesn't h=
ave a parameter for the internal container. That's because, if it uses an i=
nternal container at all, it's just an implementation detail.<br>
<br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:=
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><di=
v><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr=
"><div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8e=
x;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><div c=
lass=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0px =
0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div dir=3D"ltr"><div>
Or better yet, you can do whatever you want. It is, after all, <i>your</i> =
iterator; you can convert it into a non-const pointer to the array element =
if you like. It can have whatever private interface on it you like. You are=
not restricted to the same interface that you permit others to have.<br>
</div></div></blockquote><div><br>No, it isn't *my* iterator. The vectorset=
/flat_set/whatever just can just use the iterators of the underlying contai=
ner. It are vector/list/deque's iterators, not 'my' iterators.<br>
</div></div></div></div></blockquote></div><div><br>Every programming probl=
em can be solved by adding an additional layer of indirection. And this is =
no exception. So if, for whatever reason, you don't know that you're using =
a vector, you can simply create a wrapper iterator class that <i>contains</=
i> the underlying iterator. Your const_iterator could contain a non-const i=
nternal iterator.<br>
</div></div></blockquote><div><br>So you prefer adding a whole other layer =
of indirection over just giving functionality that is already there (.erase=
(i,i)) a proper name (and making it O(1))?<br></div></div></div></div></blo=
ckquote><div><br>vector::erase only does that as a <i>side effect</i>, not =
its intended purpose. Indeed, I'd rather that this was fixed in vector::era=
se, so that passing the same iterator will fail or something.<br><br></div>=
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div cla=
ss=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 =
..8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir=3D"ltr"><div><br>Most people don't need to perform a const_cast on=
iterators, and I would go so far as to say that if you have written code w=
here you need to, you're doing it wrong.<br></div></div></blockquote>
<div><br>Like Daniel already said, it is perfectly const-correct. It is not=
hing like a const_cast. If it weren't const-correct, erase wouldn't turn it=
s second parameter (a const_iterator) into an iterator.<br></div></div></di=
v></div></blockquote><div><br>It doesn't "turn its second parameter" into a=
nything. It <i>creates a new iterator</i>, since after the erasure, the old=
iterator may be invalid. See the difference? It's not converting anything.=
<br><br>It's const-correct because the container itself must be non-const t=
o do that. And that means that the container can <i>generate</i> whatever n=
on-const iterator it wants.<br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_913_30189968.1377426576833--
.
Author: Maurice Bos <m-ou.se@m-ou.se>
Date: Sun, 25 Aug 2013 12:45:57 +0200
Raw View
--089e0158c4107ab94204e4c359a2
Content-Type: text/plain; charset=ISO-8859-1
2013/8/25 Nicol Bolas <jmckesson@gmail.com>:
> That doesn't make sense. If you give a function a const_iterator, the
> whole point of doing that is so that it *can't* modify the data
> referenced through that iterator. So if the calling function needs to
> modify an element, then the calling function will not be using
> const_iterators. It's really that simple.
>
So if a function has both a const pointer and a non-const pointer to an
object, it can't modify it? The member function itself is non-const, so it
has non-const access to the container, it may modify anything it wants. If
i wanted to guarantee it doesn't modify anything, i would've made the
member function itself const apart from making it take a const_iterator.
> There's a reason std::upper_bound is templated on the iterator type.
>
Yes, that reason is that it can work on all containers. Not that it can
give the finger to const-correctness and take a non-const iterator even
though it doesn't modify anything. That's just a handy side effect.
Are you making a container, or a container *adapter* like std::stack and
> std::queue? Because those are completely different things with very
> different expectations.
>
> There's a reason std::flat_set doesn't have a parameter for the internal
> container. That's because, if it uses an internal container at all, it's
> just an implementation detail.
>
I guess you could call it a container adapter. It just wraps another
container, keeps some invariants true, and provides an interface almost
equal to std::set. Let's not go too deep into detail of 'flat_set' or my
implementation of a similar container. It is just one example of a context
in which to_iterator could help.
std::flat_set doesn't exist.
>
>> Like Daniel already said, it is perfectly const-correct. It is nothing
>> like a const_cast. If it weren't const-correct, erase wouldn't turn its
>> second parameter (a const_iterator) into an iterator.
>>
>
> It doesn't "turn its second parameter" into anything. It *creates a new
> iterator*, since after the erasure, the old iterator may be invalid. See
> the difference? It's not converting anything.
>
It does for std::list.
> It's const-correct because the container itself must be non-const to do
> that. And that means that the container can *generate* whatever non-const
> iterator it wants.
>
>
Exactly, the container can do that. Then why not the one who owns the
(non-const) container?
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--089e0158c4107ab94204e4c359a2
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><div class=3D"gmail_extra">2013/8/25 Nicol Bolas <span=
dir=3D"ltr"><<a href=3D"mailto:jmckesson@gmail.com" target=3D"_blank">j=
mckesson@gmail.com</a>>:</span><br><blockquote style=3D"margin:0px 0px 0=
px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"=
gmail_quote">
<span dir=3D"ltr">That doesn't make sense. If you give a function a con=
st_iterator, the whole point of doing that is so that it <i>can't</i>
modify the data referenced through that iterator. So if the calling=20
function needs to modify an element, then the calling function will not=20
be using const_iterators. It's really that simple.</span><br></blockquo=
te><div><br>So if a function has both a const pointer and a non-const point=
er to an object, it can't modify it? The member function itself is non-=
const, so it has non-const access to the container, it may modify anything =
it wants. If i wanted to guarantee it doesn't modify anything, i would&=
#39;ve made the member function itself const apart from making it take a co=
nst_iterator.<br>
=A0</div><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px soli=
d rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote">There's a re=
ason std::upper_bound is templated on the iterator type.<br></blockquote><b=
r>
Yes, that reason is that it can work on all containers. Not that it can giv=
e the finger to const-correctness and take a non-const iterator even though=
it doesn't modify anything. That's just a handy side effect.<br>
<br><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb=
(204,204,204);padding-left:1ex" class=3D"gmail_quote">Are you making a cont=
ainer, or a container <i>adapter</i> like std::stack and std::queue? Becaus=
e those are completely different things with very different expectations.<b=
r>
<br>There's
a reason std::flat_set doesn't have a parameter for the internal=20
container. That's because, if it uses an internal container at all, it&=
#39;s
just an implementation detail.<br></blockquote><div><br>I guess you could =
call it a container adapter. It just wraps another container, keeps some in=
variants true, and provides an interface almost equal to std::set. Let'=
s not go too deep into detail of 'flat_set' or my implementation of=
a similar container. It is just one example of a context in which to_itera=
tor could help.<br>
<br>std::flat_set doesn't exist. <br></div><div class=3D"gmail_quote"><=
br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;bord=
er-left:1px solid rgb(204,204,204);padding-left:1ex">
<div dir=3D"ltr"><br><div><blockquote class=3D"gmail_quote" style=3D"margin=
:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"=
><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div><br>Like Daniel alre=
ady said, it is perfectly const-correct. It is nothing like a const_cast. I=
f it weren't const-correct, erase wouldn't turn its second paramete=
r (a const_iterator) into an iterator.<br>
</div>
</div></div></div></blockquote></div><div><br>It doesn't "turn its=
second parameter" into anything. It <i>creates a new iterator</i>, si=
nce after the erasure, the old iterator may be invalid. See the difference?=
It's not converting anything.<br>
</div></div></blockquote><div><br>It does for std::list.<br><br></div><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:=
1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div>
<br>It's const-correct because the container itself must be non-const t=
o do that. And that means that the container can <i>generate</i> whatever n=
on-const iterator it wants.<br></div></div><div><div>
<br></div></div></blockquote><div><br></div></div>Exactly, the container ca=
n do that. Then why not the one who owns the (non-const) container?<br></di=
v></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--089e0158c4107ab94204e4c359a2--
.
Author: Maurice Bos <m-ou.se@m-ou.se>
Date: Sun, 25 Aug 2013 12:49:39 +0200
Raw View
--f46d042c65a7b036da04e4c3660d
Content-Type: text/plain; charset=ISO-8859-1
2013/8/25 Nicol Bolas <jmckesson@gmail.com>
> vector::erase only does that as a *side effect*, not its intended
> purpose. Indeed, I'd rather that this was fixed in vector::erase, so that
> passing the same iterator will fail or something.
>
Really? You want to make perfectly valid code like this fail?
std::vector<int> v = {1,2,3,5,6};
auto p = std::equal_range(v.begin(), v.end(), 4);
v.erase(p.first, p.second);
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--f46d042c65a7b036da04e4c3660d
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><br><div class=3D"gmail_quote">=
2013/8/25 Nicol Bolas <span dir=3D"ltr"><<a href=3D"mailto:jmckesson@gma=
il.com" target=3D"_blank">jmckesson@gmail.com</a>></span><br><blockquote=
class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px so=
lid rgb(204,204,204);padding-left:1ex">
<div>vector::erase only does that as a <i>side effect</i>, not its intended=
purpose. Indeed, I'd rather that this was fixed in vector::erase, so t=
hat passing the same iterator will fail or something.</div></blockquote>
</div><br><br></div><div class=3D"gmail_extra">Really? You want to make per=
fectly valid code like this fail?<br><pre class=3D"" id=3D"source" style=3D=
"margin-bottom:0px"><pre class=3D"">=A0 =A0 std<span class=3D"">::</span><s=
pan class=3D"">vector</span><span class=3D""><</span><span class=3D"">in=
t</span><span class=3D"">></span> v <span class=3D"">=3D</span> <span cl=
ass=3D"">{</span><span class=3D"">1</span>,<span class=3D"">2</span>,<span =
class=3D"">3</span>,<span class=3D"">5</span>,<span class=3D"">6</span><spa=
n class=3D"">}</span><span class=3D"">;</span>
=A0 =A0 <span class=3D"">auto</span> p <span class=3D"">=3D</span> std<span=
class=3D"">::</span><span class=3D"">equal_range</span><span class=3D"">(<=
/span>v.<span class=3D"">begin</span><span class=3D"">(</span><span class=
=3D"">)</span>, v.<span class=3D"">end</span><span class=3D"">(</span><span=
class=3D"">)</span>, <span class=3D"">4</span><span class=3D"">)</span><sp=
an class=3D"">;</span>
=A0 =A0 v.<span class=3D"">erase</span><span class=3D"">(</span>p.<span cla=
ss=3D"">first</span>, p.<span class=3D"">second</span><span class=3D"">)</s=
pan><span class=3D"">;</span></pre></pre><br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--f46d042c65a7b036da04e4c3660d--
.