Topic: Why do range-for loops require a variable declaration?


Author: Thiago Macieira <thiago@macieira.org>
Date: Fri, 14 Feb 2014 13:44:39 -0800
Raw View
I was trying to make the Qt foreach macro use the range for and I ran into =
the=20
$SUBJECT issue when trying to rebuild Qt. Example source code:

qdocindexfiles.cpp:591:

    QPair<ClassNode*,QString> pair;
    foreach (pair, basesList_) {
        [...]
    }

Why can't I write the following:

void f(const std::vector<int> &v)=20
{
    int i;=20
    for (i : v) {
    }
}

GCC:
error: found =E2=80=98:=E2=80=99 in nested-name-specifier, expected =E2=80=
=98::=E2=80=99

Clang:
error: for range declaration must declare a variable

While Clang's error message explains what I did wrong and GCC's just made m=
e=20
scratch my head for 10 minutes, is GCC's error message hinting at the=20
underlying reason why a declaration is necessary? If not, why does the=20
standard require a variable declaration?

This prevents a construct where the iteration variable gets used after the=
=20
loop, containing valid data.

Note that I can't rewrite the code that predeclares variables since I can't=
=20
use auto just yet and the type's name contains a comma.

--=20
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--=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/.

.


Author: "Billy O'Neal" <billy.oneal@gmail.com>
Date: Fri, 14 Feb 2014 13:52:37 -0800
Raw View
--001a11c306f064bf9e04f264d505
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Most likely because declaring loop invariant variables outside the loop is
a Bad Idea=E2=84=A2. But I'm not on the committee, so I'm not sure.

Billy O'Neal
https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
http://stackoverflow.com/users/82320/billy-oneal


On Fri, Feb 14, 2014 at 1:44 PM, Thiago Macieira <thiago@macieira.org>wrote=
:

> I was trying to make the Qt foreach macro use the range for and I ran int=
o
> the
> $SUBJECT issue when trying to rebuild Qt. Example source code:
>
> qdocindexfiles.cpp:591:
>
>     QPair<ClassNode*,QString> pair;
>     foreach (pair, basesList_) {
>         [...]
>     }
>
> Why can't I write the following:
>
> void f(const std::vector<int> &v)
> {
>     int i;
>     for (i : v) {
>     }
> }
>
> GCC:
> error: found =E2=80=98:=E2=80=99 in nested-name-specifier, expected =E2=
=80=98::=E2=80=99
>
> Clang:
> error: for range declaration must declare a variable
>
> While Clang's error message explains what I did wrong and GCC's just made
> me
> scratch my head for 10 minutes, is GCC's error message hinting at the
> underlying reason why a declaration is necessary? If not, why does the
> standard require a variable declaration?
>
> This prevents a construct where the iteration variable gets used after th=
e
> loop, containing valid data.
>
> Note that I can't rewrite the code that predeclares variables since I can=
't
> use auto just yet and the type's name contains a comma.
>
> --
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
>    Software Architect - Intel Open Source Technology Center
>       PGP/GPG: 0x6EF45358; fingerprint:
>       E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358
>
> --
>
> ---
> 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/.

--001a11c306f064bf9e04f264d505
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Most likely because declaring loop invariant variable=
s outside the loop is a Bad Idea=E2=84=A2. But I&#39;m not on the committee=
, so I&#39;m not sure.</div></div><div class=3D"gmail_extra"><br clear=3D"a=
ll"><div><div dir=3D"ltr">

<div>Billy O&#39;Neal</div><div><a href=3D"https://bitbucket.org/BillyONeal=
/" target=3D"_blank">https://github.com/BillyONeal/</a></div><div><a href=
=3D"http://stackoverflow.com/users/82320/billy-oneal" target=3D"_blank">htt=
p://stackoverflow.com/users/82320/billy-oneal</a></div>

</div></div>
<br><br><div class=3D"gmail_quote">On Fri, Feb 14, 2014 at 1:44 PM, Thiago =
Macieira <span dir=3D"ltr">&lt;<a href=3D"mailto:thiago@macieira.org" targe=
t=3D"_blank">thiago@macieira.org</a>&gt;</span> wrote:<br><blockquote class=
=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd=
ing-left:1ex">

I was trying to make the Qt foreach macro use the range for and I ran into =
the<br>
$SUBJECT issue when trying to rebuild Qt. Example source code:<br>
<br>
qdocindexfiles.cpp:591:<br>
<br>
=C2=A0 =C2=A0 QPair&lt;ClassNode*,QString&gt; pair;<br>
=C2=A0 =C2=A0 foreach (pair, basesList_) {<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 [...]<br>
=C2=A0 =C2=A0 }<br>
<br>
Why can&#39;t I write the following:<br>
<br>
void f(const std::vector&lt;int&gt; &amp;v)<br>
{<br>
=C2=A0 =C2=A0 int i;<br>
=C2=A0 =C2=A0 for (i : v) {<br>
=C2=A0 =C2=A0 }<br>
}<br>
<br>
GCC:<br>
error: found =E2=80=98:=E2=80=99 in nested-name-specifier, expected =E2=80=
=98::=E2=80=99<br>
<br>
Clang:<br>
error: for range declaration must declare a variable<br>
<br>
While Clang&#39;s error message explains what I did wrong and GCC&#39;s jus=
t made me<br>
scratch my head for 10 minutes, is GCC&#39;s error message hinting at the<b=
r>
underlying reason why a declaration is necessary? If not, why does the<br>
standard require a variable declaration?<br>
<br>
This prevents a construct where the iteration variable gets used after the<=
br>
loop, containing valid data.<br>
<br>
Note that I can&#39;t rewrite the code that predeclares variables since I c=
an&#39;t<br>
use auto just yet and the type&#39;s name contains a comma.<br>
<span class=3D"HOEnZb"><font color=3D"#888888"><br>
--<br>
Thiago Macieira - thiago (AT) <a href=3D"http://macieira.info" target=3D"_b=
lank">macieira.info</a> - thiago (AT) <a href=3D"http://kde.org" target=3D"=
_blank">kde.org</a><br>
=C2=A0 =C2=A0Software Architect - Intel Open Source Technology Center<br>
=C2=A0 =C2=A0 =C2=A0 PGP/GPG: 0x6EF45358; fingerprint:<br>
=C2=A0 =C2=A0 =C2=A0 E067 918B B660 DBD1 105C =C2=A0966C 33F5 F005 6EF4 535=
8<br>
<br>
--<br>
<br>
---<br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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">std-propo=
sals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">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>
</font></span></blockquote></div><br></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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 />

--001a11c306f064bf9e04f264d505--

.


Author: Nevin Liber <nevin@eviloverlord.com>
Date: Fri, 14 Feb 2014 16:03:56 -0600
Raw View
--047d7bfcec64d9c9ba04f264fddb
Content-Type: text/plain; charset=ISO-8859-1

On 14 February 2014 15:44, Thiago Macieira <thiago@macieira.org> wrote:

> I was trying to make the Qt foreach macro use the range for and I ran into
> the
> $SUBJECT issue when trying to rebuild Qt. Example source code:
>
> qdocindexfiles.cpp:591:
>
>     QPair<ClassNode*,QString> pair;
>     foreach (pair, basesList_) {
>         [...]
>     }
>
> Why can't I write the following:
>
> void f(const std::vector<int> &v)
> {
>     int i;
>     for (i : v) {
>     }
> }
>

That syntax is being proposed for the (rough) equivalent of:

for (auto&& i : v)

More details at n3853 Range-Based For-Loops: The Next
Generation<http://open-std.org/JTC1/SC22/WG21/docs/papers/2014/n3853.htm>.
I don't know what the status is of that paper.

This prevents a construct where the iteration variable gets used after the
> loop, containing valid data.
>

If you'd really rather use assignment than construction, why not just:

int i;
for (auto&& j : v)
{
    i = j;
}
--
 Nevin ":-)" Liber  <mailto:nevin@eviloverlord.com>  (847) 691-1404

--

---
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/.

--047d7bfcec64d9c9ba04f264fddb
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On 14 February 2014 15:44, Thiago Macieira <span dir=3D"lt=
r">&lt;<a href=3D"mailto:thiago@macieira.org" target=3D"_blank">thiago@maci=
eira.org</a>&gt;</span> wrote:<br><div class=3D"gmail_extra"><div class=3D"=
gmail_quote">

<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">I was trying to make the Qt foreach macro us=
e the range for and I ran into the<br>
$SUBJECT issue when trying to rebuild Qt. Example source code:<br>
<br>
qdocindexfiles.cpp:591:<br>
<br>
=A0 =A0 QPair&lt;ClassNode*,QString&gt; pair;<br>
=A0 =A0 foreach (pair, basesList_) {<br>
=A0 =A0 =A0 =A0 [...]<br>
=A0 =A0 }<br>
<br>
Why can&#39;t I write the following:<br>
<br>
void f(const std::vector&lt;int&gt; &amp;v)<br>
{<br>
=A0 =A0 int i;<br>
=A0 =A0 for (i : v) {<br>
=A0 =A0 }<br>
}<br></blockquote><div><br></div><div>That syntax is being proposed for the=
 (rough) equivalent of:<br><br></div><div>for (auto&amp;&amp; i : v) <br><b=
r></div><div>More details at <a href=3D"http://open-std.org/JTC1/SC22/WG21/=
docs/papers/2014/n3853.htm">n3853 Range-Based For-Loops: The Next Generatio=
n</a>.=A0 I don&#39;t know what the status is of that paper.<br>

</div><br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bord=
er-left:1px #ccc solid;padding-left:1ex">
This prevents a construct where the iteration variable gets used after the<=
br>
loop, containing valid data.<br></blockquote><div><br></div><div>If you&#39=
;d really rather use assignment than construction, why not just:<br><br></d=
iv><div>int i;<br></div><div>for (auto&amp;&amp; j : v)<br>{<br></div>

<div>=A0=A0=A0 i =3D j;<br>}<br></div></div>-- <br>=A0Nevin &quot;:-)&quot;=
 Liber=A0 &lt;mailto:<a href=3D"mailto:nevin@eviloverlord.com" target=3D"_b=
lank">nevin@eviloverlord.com</a>&gt;=A0 (847) 691-1404
</div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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 />

--047d7bfcec64d9c9ba04f264fddb--

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sat, 15 Feb 2014 00:05:05 +0200
Raw View
On 14 February 2014 23:52, Billy O'Neal <billy.oneal@gmail.com> wrote:
> Most likely because declaring loop invariant variables outside the loop is a
> Bad Idea(tm). But I'm not on the committee, so I'm not sure.
>
> Billy O'Neal
> https://github.com/BillyONeal/
> http://stackoverflow.com/users/82320/billy-oneal

The nowadays-improved minutes don't go far enough to know whether
this was discussed. The oldest paper on the subject I can find is
http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1868.html
and its corresponding wording paper
http://open-std.org/JTC1/SC22/WG21/docs/papers/2006/n1961.html
seems to have had a type-specifier-seq from the get-go.

Note that there's an extension proposal according to which
leaving out the type does something completely different, it still does
a type-specifier-seq but defaults it to auto&&:
http://open-std.org/JTC1/SC22/WG21/docs/papers/2014/n3853.htm
and this proposal has been accepted by EWG in Issaquah, so it's
in the pipeline for C++17.

>
>
> On Fri, Feb 14, 2014 at 1:44 PM, Thiago Macieira <thiago@macieira.org>
> wrote:
>>
>> I was trying to make the Qt foreach macro use the range for and I ran into
>> the
>> $SUBJECT issue when trying to rebuild Qt. Example source code:
>>
>> qdocindexfiles.cpp:591:
>>
>>     QPair<ClassNode*,QString> pair;
>>     foreach (pair, basesList_) {
>>         [...]
>>     }
>>
>> Why can't I write the following:
>>
>> void f(const std::vector<int> &v)
>> {
>>     int i;
>>     for (i : v) {
>>     }
>> }
>>
>> GCC:
>> error: found ':' in nested-name-specifier, expected '::'
>>
>> Clang:
>> error: for range declaration must declare a variable
>>
>> While Clang's error message explains what I did wrong and GCC's just made
>> me
>> scratch my head for 10 minutes, is GCC's error message hinting at the
>> underlying reason why a declaration is necessary? If not, why does the
>> standard require a variable declaration?
>>
>> This prevents a construct where the iteration variable gets used after the
>> loop, containing valid data.
>>
>> Note that I can't rewrite the code that predeclares variables since I
>> can't
>> use auto just yet and the type's name contains a comma.
>>
>> --
>> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
>>    Software Architect - Intel Open Source Technology Center
>>       PGP/GPG: 0x6EF45358; fingerprint:
>>       E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358
>>
>> --
>>
>> ---
>> 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/.
>
>
> --
>
> ---
> 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/.

--

---
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: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Fri, 14 Feb 2014 17:38:43 -0500
Raw View
On 2014-02-14 16:44, Thiago Macieira wrote:
> I was trying to make the Qt foreach macro use the range for and I ran into the
> $SUBJECT issue when trying to rebuild Qt.
>
> Note that I can't rewrite the code that predeclares variables since I can't
> use auto just yet and the type's name contains a comma.

typedef?

I'd think the real problem is that changing the semantics of 'foreach'
will break downstream code and not just Qt.

That said, it's still awkward :-).

(What compiler supports range-based for but *not* auto? I just noticed
that gcc is the other way around...)

If you could use 'auto', you might be able to do something like:

for (auto __iter : container)
   for (decl = __iter; /* magic so this only runs once */)

....but implementing 'magic' above may be sufficiently complicated so as
offset whatever benefit you were hoping for. (Maybe not for gcc though.
IIRC Q_FOREACH already does something a bit like this.)

--
Matthew

--

---
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: Thiago Macieira <thiago@macieira.org>
Date: Fri, 14 Feb 2014 16:17:22 -0800
Raw View
Em s=E1b 15 fev 2014, =E0s 00:05:05, Ville Voutilainen escreveu:
> Note that there's an extension proposal according to which
> leaving out the type does something completely different, it still does
> a type-specifier-seq but defaults it to auto&&:
> http://open-std.org/JTC1/SC22/WG21/docs/papers/2014/n3853.htm
> and this proposal has been accepted by EWG in Issaquah, so it's
> in the pipeline for C++17.

Well, this paper is in direct conflict with a possible fix to my complaint.=
 If=20
it gets accepted, it will use the syntax I want for previously-declared=20
variables to automatically declare variables.

Whereas the fix for those would be:

 for (decltype(auto) elem : range) {
 }

--=20
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--=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/.

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Fri, 14 Feb 2014 16:18:20 -0800
Raw View
Em sex 14 fev 2014, =E0s 16:03:56, Nevin Liber escreveu:
> If you'd really rather use assignment than construction, why not just:
>=20
> int i;
> for (auto&& j : v)
> {
>     i =3D j;
> }

That's a solution, it's just a bit ugly. But my main concern would be to=20
transition code using Qt's foreach macro to the new range-for. It's impossi=
ble=20
to do so now.

--=20
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--=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/.

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Fri, 14 Feb 2014 16:26:31 -0800
Raw View
Em sex 14 fev 2014, =E0s 17:38:43, Matthew Woehlke escreveu:
> for (auto __iter : container)
>    for (decl =3D __iter; /* magic so this only runs once */)
>=20
> ...but implementing 'magic' above may be sufficiently complicated so as=
=20
> offset whatever benefit you were hoping for. (Maybe not for gcc though.=
=20
> IIRC Q_FOREACH already does something a bit like this.)

Good idea, but it won't work...

We can't do that because of "break". If I nest for loops, I need to hand ov=
er=20
the breaking to the outer loop. Right now, I control the looping and exit=
=20
conditions in regular fors, but I can't do that with the range for. The onl=
y=20
way to exit it is via an actual break.
--=20
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--=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/.

.


Author: David Krauss <potswa@gmail.com>
Date: Sat, 15 Feb 2014 18:40:26 +0800
Raw View
--Apple-Mail=_80DB8899-1C10-46C9-B864-6DEB7624884B
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ISO-8859-1


On Feb 15, 2014, at 8:26 AM, Thiago Macieira <thiago@macieira.org> wrote:

> Em sex 14 fev 2014, =E0s 17:38:43, Matthew Woehlke escreveu:
>> for (auto __iter : container)
>>   for (decl =3D __iter; /* magic so this only runs once */)

Not sure what you're going after here, but range for gives you an object no=
t an iterator. But, this got me thinking...

> Good idea, but it won't work...
>=20
> We can't do that because of "break". If I nest for loops, I need to hand =
over=20
> the breaking to the outer loop. Right now, I control the looping and exit=
=20
> conditions in regular fors, but I can't do that with the range for. The o=
nly=20
> way to exit it is via an actual break.

I haven't tried this yet, but it should be possible to hack a range-for loo=
p to give you a modifiable iterator by wrapping the container object.

for ( auto & iter : hoist_iterator( container ) ) {
    ++ iter; // skip every other element
    if ( iter =3D=3D std::prev( container.end() ) ) break; // Stop just bef=
ore the end.
}

There are just a few requirements for the hoist_iterator function:
1. Returns a wrapper object. Best semantics are probably to move from an rv=
alue argument into the wrapper, or wrap a reference to an lvalue argument.
2. Wrapper object implements begin() and end(), which return wrapper iterat=
ors.
3. Wrapper iterators are InputIterators and contain the underlying iterator=
.. operator * returns a reference to the underlying iterator, and operator +=
+ and operator =3D=3D delegate to the underlying iterators. Thus the sequen=
ce iterated over is actually a sequence of iterators. They fail to be Forwa=
rdIterators because of 24.2.5/6, and allow for various other craziness, but=
 there's no problem because range-for is pure syntactic sugar with few sema=
ntic requirements.

You can also define a range class to wrap predefined iterators, allowing yo=
u to preserve the final iterator values or hack the termination condition b=
y iterator assignment. I wrote a StackOverflow answer http://stackoverflow.=
com/a/5616488/153285 on this topic, but it's outdated now.

--=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/.

--Apple-Mail=_80DB8899-1C10-46C9-B864-6DEB7624884B
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;"><br><div><div>On Feb 1=
5, 2014, at 8:26 AM, Thiago Macieira &lt;<a href=3D"mailto:thiago@macieira.=
org">thiago@macieira.org</a>&gt; wrote:</div><br class=3D"Apple-interchange=
-newline"><blockquote type=3D"cite">Em sex 14 fev 2014, =E0s 17:38:43, Matt=
hew Woehlke escreveu:<br><blockquote type=3D"cite">for (auto __iter : conta=
iner)<br> &nbsp;&nbsp;for (decl =3D __iter; /* magic so this only runs once=
 */)<br></blockquote></blockquote><div><br></div><div>Not sure what you&rsq=
uo;re going after here, but range for gives you an object not an iterator. =
But, this got me thinking&hellip;</div><br><blockquote type=3D"cite">Good i=
dea, but it won't work...<br><br>We can't do that because of "break". If I =
nest for loops, I need to hand over <br>the breaking to the outer loop. Rig=
ht now, I control the looping and exit <br>conditions in regular fors, but =
I can't do that with the range for. The only <br>way to exit it is via an a=
ctual break.<br></blockquote><div><br></div><div>I haven&rsquo;t tried this=
 yet, but it should be possible to hack a range-for loop to give you a modi=
fiable iterator by wrapping the container object.</div><div><br></div><div>=
<font face=3D"Courier">for ( auto &amp; iter : hoist_iterator( container ) =
) {</font></div><div><font face=3D"Courier">&nbsp; &nbsp; ++ iter; // skip =
every other element</font></div><div><font face=3D"Courier">&nbsp; &nbsp; i=
f ( iter =3D=3D std::prev( container.end() ) ) break; // Stop just before t=
he end.</font></div><font face=3D"Courier">}</font></div><div><br></div><di=
v>There are just a few requirements for the&nbsp;<font face=3D"Courier">hoi=
st_iterator</font>&nbsp;function:</div><div>1. Returns a wrapper object. Be=
st semantics are probably to move from an rvalue argument into the wrapper,=
 or wrap a reference to an lvalue argument.</div><div>2. Wrapper object imp=
lements <font face=3D"Courier">begin()</font> and <font face=3D"Courier">en=
d()</font>, which return wrapper iterators.</div><div>3. Wrapper iterators =
are InputIterators and contain the underlying iterator.&nbsp;<font face=3D"=
Courier">operator *</font>&nbsp;returns a reference to the underlying itera=
tor, and <font face=3D"Courier">operator ++</font>&nbsp;and <font face=3D"C=
ourier">operator =3D=3D</font>&nbsp;delegate to the underlying iterators. T=
hus the sequence iterated over is actually a sequence of iterators. They fa=
il to be ForwardIterators because of 24.2.5/6, and allow for various other =
craziness, but there&rsquo;s no problem because range-for is pure syntactic=
 sugar with few semantic requirements.</div><div><br></div><div>You can als=
o define a <font face=3D"Courier">range</font> class to wrap predefined ite=
rators, allowing you to preserve the final iterator values or hack the term=
ination condition by iterator assignment. I wrote a StackOverflow answer <a=
 href=3D"http://stackoverflow.com/a/5616488/153285">http://stackoverflow.co=
m/a/5616488/153285</a> on this topic, but it&rsquo;s outdated now.</div><di=
v><br></div></body></html>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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 />

--Apple-Mail=_80DB8899-1C10-46C9-B864-6DEB7624884B--

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Mon, 17 Feb 2014 11:25:24 -0500
Raw View
On 2014-02-15 05:40, David Krauss wrote:
> On Feb 15, 2014, at 8:26 AM, Thiago Macieira wrote:
>> Em sex 14 fev 2014, =C3=A0s 17:38:43, Matthew Woehlke escreveu:
>>> for (auto __iter : container)
>>>    for (decl =3D __iter; /* magic so this only runs once */)
>
> Not sure what you're going after here, but range for gives you an object =
not an iterator.

I know... poor choice of name for the 'private' value holder is all :-).

>> We can't do that because of "break". If I nest for loops, I need to hand=
 over
>> the breaking to the outer loop. Right now, I control the looping and exi=
t
>> conditions in regular fors, but I can't do that with the range for. The =
only
>> way to exit it is via an actual break.

Too bad you can't write 'if (decl =3D __iter, true)' :-(.

> I haven't tried this yet, but it should be possible to hack a range-for l=
oop to give you a modifiable iterator by wrapping the container object.
>
> for ( auto & iter : hoist_iterator( container ) ) {

This won't work; you can't write anything with a '{' because it requires=20
users to add a closing '}' to their code. (Which is why constructs like=20
this tend to have strange things in their initialization and compare steps.=
)

--=20
Matthew

--=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/.

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Mon, 17 Feb 2014 11:37:37 -0500
Raw View
On 2014-02-17 11:25, Matthew Woehlke wrote:
> On 2014-02-15 05:40, David Krauss wrote:
>> On Feb 15, 2014, at 8:26 AM, Thiago Macieira wrote:
>>> Em sex 14 fev 2014, =C3=A0s 17:38:43, Matthew Woehlke escreveu:
>>>> for (auto __iter : container)
>>>>    for (decl =3D __iter; /* magic so this only runs once */)
>>
>> Not sure what you're going after here, but range for gives you an
>> object not an iterator.
>
> I know... poor choice of name for the 'private' value holder is all :-).
>
>>> We can't do that because of "break". If I nest for loops, I need to
>>> hand over
>>> the breaking to the outer loop. Right now, I control the looping and
>>> exit
>>> conditions in regular fors, but I can't do that with the range for.
>>> The only
>>> way to exit it is via an actual break.
>
> Too bad you can't write 'if (decl =3D __iter, true)' :-(.
>
>> I haven't tried this yet, but it should be possible to hack a
>> range-for loop to give you a modifiable iterator by wrapping the
>> container object.
>>
>> for ( auto & iter : hoist_iterator( container ) ) {
>
> This won't work; you can't write anything with a '{' because it requires
> users to add a closing '}' to their code. (Which is why constructs like
> this tend to have strange things in their initialization and compare
> steps.)

That said... I guess/hope you are already wrapping the container in=20
order (for Qt containers at least?) to make a copy of it so that=20
mutating the original container inside the loop is safe? (Note to folks=20
unfamiliar with Qt: this is the current/historic behavior of Q_FOREACH.)

What if this wrapper had a mutating iterator?

Here's a sketch of what I am thinking


for (...stuff to set up the container wrapper...)
   for (auto&& __val : __wrapper)
     for (decl =3D __val; __wrapper.test(); __wrapper.next())

This would be set up so that test() returns 'true' immediately after=20
wrapper construction or operator++ on the wrapper iterator and then sets=20
an internal state to return false next time. Additionally, test() sets=20
an internal state so that the iterator operator!=3D returns false, which=20
is cleared by calling next().

The idea is to arrange for the '!=3D end' comparison to be false any time=
=20
you see a call chain like:

   ctor or iterator operator++
   test()

....but not:

   ctor or iterator operator++
   test()
   next()
   test()

....which will happen when the user uses 'break' to escape the inner=20
loop. I think if it is done correctly, you can use this idea to cause=20
the range-based for to exit when the inner loop exits, using next() as=20
the control for that behavior.

--=20
Matthew

--=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/.

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Mon, 17 Feb 2014 14:32:15 -0800
Raw View
Em seg 17 fev 2014, =E0s 11:37:37, Matthew Woehlke escreveu:
> Here's a sketch of what I am thinking
>=20
>=20
> for (...stuff to set up the container wrapper...)
>    for (auto&& __val : __wrapper)
>      for (decl =3D __val; __wrapper.test(); __wrapper.next())

I don't think I'm interested. Q_FOREACH already does the work with two fors=
..=20
If I can't get it with one or two with better code generation, it doesn't m=
ake=20
sense to change.

--=20
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--=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/.

.


Author: Matthew Woehlke <matthew.woehlke@kitware.com>
Date: Mon, 17 Feb 2014 19:12:22 -0500
Raw View
On 2014-02-17 17:32, Thiago Macieira wrote:
> Em seg 17 fev 2014, =C3=A0s 11:37:37, Matthew Woehlke escreveu:
>> Here's a sketch of what I am thinking
>>
>>
>> for (...stuff to set up the container wrapper...)
>>     for (auto&& __val : __wrapper)
>>       for (decl =3D __val; __wrapper.test(); __wrapper.next())
>
> I don't think I'm interested. Q_FOREACH already does the work with two fo=
rs.
> If I can't get it with one or two with better code generation, it doesn't=
 make
> sense to change.

Agreed; it's an interesting exercise in whether or not it's possible,=20
but - as I wrote in my original message in this thread - not clear what=20
benefit you're hoping to get. (Besides less code, which seems=20
unattainable :-(.)

--=20
Matthew

--=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/.

.


Author: David Krauss <potswa@gmail.com>
Date: Tue, 18 Feb 2014 08:18:53 +0800
Raw View
--Apple-Mail=_EF167EAC-A989-42A8-8C1C-FB91ED3AB871
Content-Type: text/plain; charset=ISO-8859-1


On Feb 18, 2014, at 12:25 AM, Matthew Woehlke <mw_triad@users.sourceforge.net> wrote:

> On 2014-02-15 05:40, David Krauss wrote:
>> for ( auto & iter : hoist_iterator( container ) ) {
>
> This won't work; you can't write anything with a '{' because it requires users to add a closing '}' to their code. (Which is why constructs like this tend to have strange things in their initialization and compare steps.)

The { isn't an integral part of my suggestion. There's really no excuse for having that kind of limitation on your macros, but you can at least work around it with a lambda expression.

--

---
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/.

--Apple-Mail=_EF167EAC-A989-42A8-8C1C-FB91ED3AB871
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;"><br><div><div>On Feb 1=
8, 2014, at 12:25 AM, Matthew Woehlke &lt;<a href=3D"mailto:mw_triad@users.=
sourceforge.net">mw_triad@users.sourceforge.net</a>&gt; wrote:</div><br cla=
ss=3D"Apple-interchange-newline"><blockquote type=3D"cite">On 2014-02-15 05=
:40, David Krauss wrote:<br><blockquote type=3D"cite">for ( auto &amp; iter=
 : hoist_iterator( container ) ) {</blockquote><br>This won't work; you can=
't write anything with a '{' because it requires users to add a closing '}'=
 to their code. (Which is why constructs like this tend to have strange thi=
ngs in their initialization and compare steps.)<br></blockquote><div><br></=
div><div>The <font face=3D"Courier">{</font> isn&rsquo;t an integral part o=
f my suggestion. There&rsquo;s really no excuse for having that kind of lim=
itation on your macros, but you can at least work around it with a lambda e=
xpression.</div><div><br></div></div></body></html>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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 />

--Apple-Mail=_EF167EAC-A989-42A8-8C1C-FB91ED3AB871--

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Mon, 17 Feb 2014 19:34:52 -0500
Raw View
On 2014-02-17 19:18, David Krauss wrote:
> The { isn't an integral part of my suggestion. There's really no
> excuse for having that kind of limitation on your macros,

Eh? Maybe I am confused because I don't see where the loop body fits
into your version.

Keep in mind we are trying to implement 'foreach', used like:

   foreach (int i, container)
     foo(i);

   int j;
   foreach (j, container) {
     ...
   }

....so whatever 'foreach' is, should behave like a control statement...
braces optional, no extra "special" code needed after using it.

--
Matthew

--

---
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: David Krauss <potswa@gmail.com>
Date: Tue, 18 Feb 2014 08:40:37 +0800
Raw View
--Apple-Mail=_876A6170-36C2-4163-AB74-206ADD139537
Content-Type: text/plain; charset=ISO-8859-1


On Feb 18, 2014, at 8:34 AM, Matthew Woehlke <mw_triad@users.sourceforge.net> wrote:

> On 2014-02-17 19:18, David Krauss wrote:
>> The { isn't an integral part of my suggestion. There's really no
>> excuse for having that kind of limitation on your macros,
>
> Eh? Maybe I am confused because I don't see where the loop body fits into your version.

I proposed a function hoist_iterator() which causes the for loop to give you an iterator which persists throughout the loop, instead of a value.

> Keep in mind we are trying to implement 'foreach', used like:
>
>  foreach (int i, container)
>    foo(i);
>
>  int j;
>  foreach (j, container) {
>    ...
>  }

See the linked StackOverflow for persistence before and after the loop.

> ...so whatever 'foreach' is, should behave like a control statement... braces optional, no extra "special" code needed after using it.

Well, it's a macro. And you'll need two macros to accommodate both illustrations above, unless you actually mean that one translates to the other -- which would be very unintuitive scoping.

--

---
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/.

--Apple-Mail=_876A6170-36C2-4163-AB74-206ADD139537
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=ISO-8859-1

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;"><br><div><div>On Feb 1=
8, 2014, at 8:34 AM, Matthew Woehlke &lt;<a href=3D"mailto:mw_triad@users.s=
ourceforge.net">mw_triad@users.sourceforge.net</a>&gt; wrote:</div><br clas=
s=3D"Apple-interchange-newline"><blockquote type=3D"cite">On 2014-02-17 19:=
18, David Krauss wrote:<br><blockquote type=3D"cite">The { isn't an integra=
l part of my suggestion. There's really no<br>excuse for having that kind o=
f limitation on your macros,<br></blockquote><br>Eh? Maybe I am confused be=
cause I don't see where the loop body fits into your version.<br></blockquo=
te><div><br></div><div>I proposed a function <font face=3D"Courier">hoist_i=
terator()</font>&nbsp;which causes the for loop to give you an iterator whi=
ch persists throughout the loop, instead of a value.</div><br><blockquote t=
ype=3D"cite">Keep in mind we are trying to implement 'foreach', used like:<=
br><br> &nbsp;foreach (int i, container)<br> &nbsp;&nbsp;&nbsp;foo(i);<br><=
br> &nbsp;int j;<br> &nbsp;foreach (j, container) {<br> &nbsp;&nbsp;&nbsp;.=
...<br> &nbsp;}<br></blockquote><div><br></div><div>See the linked StackOver=
flow for persistence before and after the loop.</div><br><blockquote type=
=3D"cite">...so whatever 'foreach' is, should behave like a control stateme=
nt... braces optional, no extra "special" code needed after using it.<br></=
blockquote></div><br><div>Well, it&rsquo;s a macro. And you&rsquo;ll need t=
wo macros to accommodate both illustrations above, unless you actually mean=
 that one translates to the other &mdash; which would be very unintuitive s=
coping.</div><div><br></div></body></html>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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 />

--Apple-Mail=_876A6170-36C2-4163-AB74-206ADD139537--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Mon, 17 Feb 2014 21:10:32 -0800
Raw View
Em seg 17 fev 2014, =E0s 19:12:22, Matthew Woehlke escreveu:
> Agreed; it's an interesting exercise in whether or not it's possible,=20
> but - as I wrote in my original message in this thread - not clear what=
=20
> benefit you're hoping to get. (Besides less code, which seems=20
> unattainable :-(.)

Right now, the compilers aren't optimising the control words fully. All bui=
lds=20
I've tried indicate that the compilers fail to see the Q_FOREACH for what i=
t's=20
supposed to be. The control word is always set and rechecked, even when the=
=20
result is obvious. Worse, it's sometimes spilled to memory.

My first attempt was to use the range-for, which would avoid having to have=
 a=20
control word in the first place.

If that doesn't work, I'll file missed optimisation bugs with Clang and GCC=
,=20
hoping that they have the time to fix it.
--=20
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--=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/.

.