Topic: Allow values of void


Author: martin.molzer@gmx.de
Date: Thu, 30 Jul 2015 13:49:44 -0700 (PDT)
Raw View
------=_Part_65_1239730751.1438289384012
Content-Type: multipart/alternative;
 boundary="----=_Part_66_1863917241.1438289384013"

------=_Part_66_1863917241.1438289384013
Content-Type: text/plain; charset=UTF-8

Currently, declaring a variable as void is forbidden. That makes sense but
restricts some cases of generic programming.

The intent is, to allow variables of type void but make them carry no
actual data.

Consider:

template<typename R, typename Q, typename... A>
Q concat(R (*fn)(A...), Q (*fn2)(R), A&&... a)
{
  R result = fn(a...);
  return fn2(result);
}

int convert(float f)
{
  return f;
}

void print(int a)
{
  std::cout << a;
}

auto convert_and_print = std::bind(concat<int, void, float>, convert, print,
std::placeholders::_1);
convert_and_print(3.5f);

This method can be used, combined with bind to combine two methods into
one. But it fails, when the return type of the first function is void. Why
would we need that, well consider

void print(int a)
{
  std::cout << a;
}
void printline()
{
  std::cout << std::endl;
}
//auto print_with_ln = std::bind(concat<void, void, int>, print, printline,
std::placeholders::_1);
// Fails horribly at the moment

I consider this a bad design by the language and thus propose the following:

A variable of type void

   - occupies no space (sizeof(void) == 0)
   - holds no value and can not be converted to any other type.
   - has an alignment of 1 (aligned to a storage unit boundary).
   - defines the following operators
      - defines no other operators but == and !=
      - compares equal to all other void variables (up to discussion)
   - is "swallowed" when given as an argument to a function. It appears as
   if it wasn't given (but the expression giving this void is evaluated).


Certainly, there is a second point we have to take care of.

A function with the signature R(A..., B...) also has the signature R(A...,
void, B...) with typename R and typename...A, typename... B. This is to be
able to bind no-args functions as a function accepting a void argument, and
so forth.

With this the example print_with_ln would certainly compile and execute.

 -- WE

--

---
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_66_1863917241.1438289384013
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Currently, declaring a variable as void is forbidden. That=
 makes sense but restricts some cases of generic programming.<br><br>The in=
tent is, to allow variables of type void but make them carry no actual data=
..<br><br>Consider:<br><br><div class=3D"prettyprint" style=3D"background-co=
lor: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: so=
lid; border-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"=
><div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled=
-by-prettify">template</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">&lt;</span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">typename</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> R</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
 style=3D"color: #008;" class=3D"styled-by-prettify">typename</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> Q</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">typename</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">...</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> A</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><br>Q concat</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">R </=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">(*</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">fn</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">)(</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">A</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">...),</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> Q </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">(*</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">fn2</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">)(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">R</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">),</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> A</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&amp;&amp;...</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> a</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br>=C2=A0 R result </span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> fn</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify">a</span><span style=3D"color: #660;" class=3D"styled-by-prettify">...)=
;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=
=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">return=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> fn2</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">result</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br><br></span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> convert</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">(</span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">float</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> f</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">return</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> f</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br><br></span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">void</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">print<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">int</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> a</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br>=C2=A0 std</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify">cout </span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">&lt;&lt;</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> a</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">}</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> convert_and_print </span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> std</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify">bind</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">concat</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">&lt;</span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">int</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">void</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">float</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">&gt;,</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> convert</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>print</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> std</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">placeholders</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">_1</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br>convert_and_print</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #066;" c=
lass=3D"styled-by-prettify">3.5f</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br></span></div></code></div><br>This method can be used, =
combined with bind to combine two methods into one. But it fails, when the =
return type of the first function is void. Why would we need that, well con=
sider<br><br><div class=3D"prettyprint" style=3D"background-color: rgb(250,=
 250, 250); border-color: rgb(187, 187, 187); border-style: solid; border-w=
idth: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=
=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">void</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #008;" class=3D"styled-by-prettify">print</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> a</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br>=C2=A0 std</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">cout </span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>&lt;&lt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
a</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: =
#008;" class=3D"styled-by-prettify">void</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> printline</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">()</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br>=C2=A0 std</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify">cout </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
&lt;&lt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> s=
td</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify">endl</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br></span><span style=3D"color: #800;" class=
=3D"styled-by-prettify">//auto print_with_ln =3D std::bind(concat&lt;void, =
void, int&gt;, print, printline, std::placeholders::_1);</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"co=
lor: #800;" class=3D"styled-by-prettify">// Fails horribly at the moment</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span></=
div></code></div><br>I consider this a bad design by the language and thus =
propose the following:<br><br>A variable of type void<br><ul><li>occupies n=
o space (sizeof(void) =3D=3D 0)</li><li>holds no value and can not be conve=
rted to any other type.</li><li>has an alignment of 1 (aligned to a storage=
 unit boundary).</li><li>defines the following operators</li><ul><li>define=
s no other operators but =3D=3D and !=3D</li><li>compares equal to all othe=
r void variables (up to discussion)</li></ul><li>is &quot;swallowed&quot; w=
hen given as an argument to a function. It appears as if it wasn&#39;t give=
n (but the expression giving this void is evaluated).</li></ul><br>Certainl=
y, there is a second point we have to take care of.<br><br>A function with =
the signature R(A..., B...) also has the signature R(A..., void, B...) with=
 typename R and typename...A, typename... B. This is to be able to bind no-=
args functions as a function accepting a void argument, and so forth.<br><b=
r>With this the example print_with_ln would certainly compile and execute.<=
br><br>=C2=A0-- WE<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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_66_1863917241.1438289384013--
------=_Part_65_1239730751.1438289384012--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Thu, 30 Jul 2015 14:06:29 -0700
Raw View
On Thursday 30 July 2015 13:49:44 martin.molzer@gmx.de wrote:
>    - is "swallowed" when given as an argument to a function. It appears as
>    if it wasn't given (but the expression giving this void is evaluated).

This would suddenly allow:

void f(int, int);
void g();

int main()
{
 f(1, g(), 1);
}

Did f get three arguments? No, it got two, because g() was void and got
swallowed.

The above could be done today with:

 f(1, (g(), 1));

This suddenly also allows dereferencing a void* pointer.

template <typename T, T (*Func)()>
void h(T *ptr)
{
 *ptr = Func();
}

Should the compiler warn that ptr wasn't used?
--
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/.

.


Author: martin.molzer@gmx.de
Date: Thu, 30 Jul 2015 14:17:42 -0700 (PDT)
Raw View
------=_Part_4_873843353.1438291063133
Content-Type: multipart/alternative;
 boundary="----=_Part_5_1989134061.1438291063134"

------=_Part_5_1989134061.1438291063134
Content-Type: text/plain; charset=UTF-8



> The above could be done today with:
>
>         f(1, (g(), 1));
>

Note that there is a subtle difference: The way we can do it now puts a
sequence point between the evaluation of g() and 1.

This suddenly also allows dereferencing a void* pointer.
>
> template <typename T, T (*Func)()>
> void h(T *ptr)
> {
>         *ptr = Func();
> }
>
> Should the compiler warn that ptr wasn't used?
>

Why is that a bad thing? I wouldn't even say that a warning was need, but
you are right that one has to define the semantics for a void pointer.
Possibly something like dereferencing a void pointer results in an
(imaginary) reference to a void value. Asignment doesn't do anything at
all, thus "it is safe" to do so.

If this was for the sake of generalizing generic programming methods, I
would happily try to come up with good stuff.


--

---
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_5_1989134061.1438291063134
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">The above=
 could be done today with:
<br>
<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0f(1, (g(), 1));
<br></blockquote><div>=C2=A0</div><div>Note that there is a subtle differen=
ce: The way we can do it now puts a sequence point between the evaluation o=
f g() and 1.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin=
: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">This=
 suddenly also allows dereferencing a void* pointer.
<br>
<br>template &lt;typename T, T (*Func)()&gt;
<br>void h(T *ptr)
<br>{
<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0*ptr =3D Func();
<br>}
<br>
<br>Should the compiler warn that ptr wasn&#39;t used?<br></blockquote><div=
><br>Why is that a bad thing? I wouldn&#39;t even say that a warning was ne=
ed, but you are right that one has to define the semantics for a void point=
er. Possibly something like dereferencing a void pointer results in an (ima=
ginary) reference to a void value. Asignment doesn&#39;t do anything at all=
, thus &quot;it is safe&quot; to do so.<br><br>If this was for the sake of =
generalizing generic programming methods, I would happily try to come up wi=
th good stuff.<br></div><div>=C2=A0</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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_5_1989134061.1438291063134--
------=_Part_4_873843353.1438291063133--

.


Author: Andrey Semashev <andrey.semashev@gmail.com>
Date: Fri, 31 Jul 2015 00:23:24 +0300
Raw View
On Thu, Jul 30, 2015 at 11:49 PM,  <martin.molzer@gmx.de> wrote:
> Currently, declaring a variable as void is forbidden. That makes sense but
> restricts some cases of generic programming.
>
> A variable of type void
>
> occupies no space (sizeof(void) == 0)

No (complete) type can have sizeof(T) == 0 because this would break
strict aliasing rules (i.e. no two objects can have the same memory
address). Void is incomplete, that's why you can't create values of it
or apply sizeof to it. You're asking to make it a complete type and as
such you will have to give it a size and a non-empty set of values
(even if that set consists of a single value).

I think this is a bad idea for multiple reasons. First, I don't think
the example you've given is motivating enough to make such drastic
changes to the language type system. Second, if changed this way, void
becomes no different from other types in that you have to return its
values from void functions, and that's a breaking change. You could go
further and make void yet special in that its value is implied in void
function returns, but that doesn't strike me as a sign of good design.
Third, void values will have to be actually passed around, and that
may break ABI as well. There are probably many more reasons that I'm
forgetting now.

What instead you could propose is to relax some rules on function call
syntax so that this is allowed:

void foo();
void bar();

void concat()
{
    return foo(bar());
}

This doesn't require changes to the type system and just adds some
syntax uniformity.

--

---
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: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Thu, 30 Jul 2015 15:06:07 -0700
Raw View
--047d7bd7648e00a0a6051c1ee9e7
Content-Type: text/plain; charset=UTF-8

On Thu, Jul 30, 2015 at 1:49 PM, <martin.molzer@gmx.de> wrote:

> Currently, declaring a variable as void is forbidden. That makes sense but
> restricts some cases of generic programming.
>
> The intent is, to allow variables of type void but make them carry no
> actual data.
>

Yes!!! Working with void types are a pain in C++ in generic code and you
are frequently forced to make needless specializations because of it. For
examples, look at things like futures, expected, etc.

Someone with Sean Parent's email on hand should CC him, since he has
expressed interested in exactly this notion and I'm sure he's given it a
fair amount of thought already.

A variable of type void
>
>    - occupies no space (sizeof(void) == 0)
>
> This might be weird because of its implications with respect to the rest
of the language as it currently is. For instance, can you make an array of
them (you should logically be able to)? I think if we were starting from
scratch with C++, size 0 would be a reasonable choice, but IIUC, it would
be difficult to change now. That said, this doesn't rule out making
instances of void types and using them in generic code.

>
>    - defines the following operators
>       - defines no other operators but == and !=
>       - compares equal to all other void variables (up to discussion)
>
> I see no reason to not support all of the comparisons. There's no reason
to not support <, for instance. Also, void types should be assignable. They
should be regular types.

>
>    - is "swallowed" when given as an argument to a function. It appears
>    as if it wasn't given (but the expression giving this void is evaluated).
>
> I disagree here. You still should be able to pass void and have them
really be separate arguments. Consider the following example in generic
code:

//////////
template <class... Fun>
auto tuple_of_results(Fun... fun) {
  return std::make_tuple(fun()...);
}
//////////

Ideally, the above code should work for any return types, including void.
If you strictly swallow void, this wouldn't work. Going further, to be
truly proper, reference-to-void also should be supported (for instance,
std::tie in generic code or std::forward_as_tuple, both of which are
common).

Here's a somewhat wacky idea, but I'm just throwing it out there. Instead
of "swallowing" void, allow passing *nothing* as an argument to a function
whose parameter is void (and consider functions that take no parameters to
be equivalent in usage, though maybe not in function type, to functions
that take a single void parameter).

For example:

//////////
template <class T>
void foo(T arg) {}

int main() {
  foo<void>(); // This would work
  foo<void>(void{}); // This also works (default-construct a void)
  foo<void>(foo<void>()); // This also works
}
//////////

With respect to something like the definition of std::promise, it should
allow for std::promise<void> to not require a specialization and instead
just use the default template definition, and you could still use it the
same way that you would today in non-generic code with the specialization
that is specified (for instance, set_value() would just work).

In cases where "void" appears not as the sole parameter type, we can even
extrapolate and do the same thing -- keep in mind that users still need to
pass an argument, even if that argument is nothing:

//////////
// Notice that we can pass "nothing" here. This comes naturally from the
above rule.
tuple<int, void, char, void, void> foo(5, , 'a', , );
//////////

This type of syntax actually has precedent in C++ already, since this is
how you pass empty tokens to macros in C and C++.

Ultimately, if we are to have properly designed void types, they should not
be particularly special. They should just be regular types like most other
(proper) C++.

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
hu, Jul 30, 2015 at 1:49 PM,  <span dir=3D"ltr">&lt;<a href=3D"mailto:marti=
n.molzer@gmx.de" target=3D"_blank">martin.molzer@gmx.de</a>&gt;</span> wrot=
e:<br><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">Currently, declaring =
a variable as void is forbidden. That makes sense but restricts some cases =
of generic programming.<br><br>The intent is, to allow variables of type vo=
id but make them carry no actual data.<br></div></blockquote><div><br></div=
><div>Yes!!! Working with void types are a pain in C++ in generic code and =
you are frequently forced to make needless specializations because of it. F=
or examples, look at things like futures, expected, etc.</div><div><br></di=
v><div>Someone with Sean Parent&#39;s email on hand should CC him, since he=
 has expressed interested in exactly this notion and I&#39;m sure he&#39;s =
given it a fair amount of thought already.</div><div><br></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">A variable of type void<br><ul><li>occu=
pies no space (sizeof(void) =3D=3D 0)</li></ul></div></blockquote><div>This=
 might be weird because of its implications with respect to the rest of the=
 language as it currently is. For instance, can you make an array of them (=
you should logically be able to)? I think if we were starting from scratch =
with C++, size 0 would be a reasonable choice, but IIUC, it would be diffic=
ult to change now. That said, this doesn&#39;t rule out making instances of=
 void types and using them in generic code.</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"><ul><li>defines the following operators</li><ul><li>d=
efines no other operators but =3D=3D and !=3D</li><li>compares equal to all=
 other void variables (up to discussion)</li></ul></ul></div></blockquote><=
div>I see no reason to not support all of the comparisons. There&#39;s no r=
eason to not support &lt;, for instance. Also, void types should be assigna=
ble. They should be regular types.</div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div=
 dir=3D"ltr"><ul><li>is &quot;swallowed&quot; when given as an argument to =
a function. It appears as if it wasn&#39;t given (but the expression giving=
 this void is evaluated).</li></ul></div></blockquote><div>I disagree here.=
 You still should be able to pass void and have them really be separate arg=
uments. Consider the following example in generic code:</div><div><br></div=
><div>//////////</div><div>template &lt;class... Fun&gt;</div><div>auto tup=
le_of_results(Fun... fun) {</div><div>=C2=A0 return std::make_tuple(fun()..=
..);</div><div>}</div><div>//////////</div><div><br></div><div>Ideally, the =
above code should work for any return types, including void. If you strictl=
y swallow void, this wouldn&#39;t work. Going further, to be truly proper, =
reference-to-void also should be supported (for instance, std::tie in gener=
ic code or std::forward_as_tuple, both of which are common).</div><div><br>=
</div><div>Here&#39;s a somewhat wacky idea, but I&#39;m just throwing it o=
ut there. Instead of &quot;swallowing&quot; void, allow passing <i>nothing<=
/i>=C2=A0as an argument to a function whose parameter is void (and consider=
 functions that take no parameters to be equivalent in usage, though maybe =
not in function type, to functions that take a single void parameter).</div=
><div><br></div><div>For example:</div><div><br></div><div>//////////</div>=
<div>template &lt;class T&gt;</div><div>void foo(T arg) {}</div><div><br></=
div><div>int main() {</div><div>=C2=A0 foo&lt;void&gt;(); // This would wor=
k</div><div>=C2=A0 foo&lt;void&gt;(void{}); // This also works (default-con=
struct a void)</div><div>=C2=A0 foo&lt;void&gt;(foo&lt;void&gt;()); // This=
 also works</div><div>}</div><div>//////////</div><div><br></div><div>With =
respect to something like the definition of std::promise, it should allow f=
or std::promise&lt;void&gt; to not require a specialization and instead jus=
t use the default template definition, and you could still use it the same =
way that you would today in non-generic code with the specialization that i=
s specified (for instance, set_value() would just work).</div><div><br></di=
v><div>In cases where &quot;void&quot; appears not as the sole parameter ty=
pe, we can even extrapolate and do the same thing -- keep in mind that user=
s still need to pass an argument, even if that argument is nothing:</div><d=
iv><br></div><div>//////////</div><div>// Notice that we can pass &quot;not=
hing&quot; here. This comes naturally from the above rule.</div><div>tuple&=
lt;int, void, char, void, void&gt; foo(5, , &#39;a&#39;, , );</div><div>///=
///////</div><div><br></div><div>This type of syntax actually has precedent=
 in C++ already, since this is how you pass empty tokens to macros in C and=
 C++.</div><div><br></div><div>Ultimately, if we are to have properly desig=
ned void types, they should not be particularly special. They should just b=
e regular types like most other (proper) C++.</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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--047d7bd7648e00a0a6051c1ee9e7--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Thu, 30 Jul 2015 15:40:11 -0700
Raw View
--047d7bd7648ed6ed57051c1f629b
Content-Type: text/plain; charset=UTF-8

On Thu, Jul 30, 2015 at 3:06 PM, Matt Calabrese <calabrese@google.com>
wrote:
>
> (and consider functions that take no parameters to be equivalent in usage,
> though maybe not in function type, to functions that take a single void
> parameter).
>

To avoid breaking changes, for functions declared using "void" as the
parameter type directly (I.E. where void isn't a typedef or something
dependent on a template parameter), the function type is a nullary
function, as has always been the case. On the other hand, if the parameter
type is "void" but that type came from a typedef, or is dependent on a
template parameter (these are illegal in current C++), then the function
type is unary, taking that void parameter. In this way, all existing
function declarations would have the same exact type that they always had,
but declaration of void functions in generic code would work in the way
that is expected. If you want to make a unary function that takes a void
parameter and you are in non-generic code, you can still do this by using a
typedef of void (or an identity alias, passing in void).

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
hu, Jul 30, 2015 at 3:06 PM, Matt Calabrese <span dir=3D"ltr">&lt;<a href=
=3D"mailto:calabrese@google.com" target=3D"_blank">calabrese@google.com</a>=
&gt;</span> wrote:<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 clas=
s=3D"gmail_extra"><div class=3D"gmail_quote"><div>(and consider functions t=
hat take no parameters to be equivalent in usage, though maybe not in funct=
ion type, to functions that take a single void parameter).</div></div></div=
></div></blockquote><div><br></div><div>To avoid breaking changes, for func=
tions declared using &quot;void&quot; as the parameter type directly (I.E. =
where void isn&#39;t a typedef or something dependent on a template paramet=
er), the function type is a nullary function, as has always been the case. =
On the other hand, if the parameter type is &quot;void&quot; but that type =
came from a typedef, or is dependent on a template parameter (these are ill=
egal in current C++), then the function type is unary, taking that void par=
ameter. In this way, all existing function declarations would have the same=
 exact type that they always had, but declaration of void functions in gene=
ric code would work in the way that is expected. If you want to make a unar=
y function that takes a void parameter and you are in non-generic code, you=
 can still do this by using a typedef of void (or an identity alias, passin=
g in void).</div><div><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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--047d7bd7648ed6ed57051c1f629b--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Thu, 30 Jul 2015 15:56:48 -0700
Raw View
--001a1134af4044b1bd051c1f9e99
Content-Type: text/plain; charset=UTF-8

On Thu, Jul 30, 2015 at 3:06 PM, Matt Calabrese <calabrese@google.com>
wrote:
>
>
> In cases where "void" appears not as the sole parameter type, we can even
> extrapolate and do the same thing -- keep in mind that users still need to
> pass an argument, even if that argument is nothing:
>
> //////////
> // Notice that we can pass "nothing" here. This comes naturally from the
> above rule.
> tuple<int, void, char, void, void> foo(5, , 'a', , );
> //////////
>
> This type of syntax actually has precedent in C++ already, since this is
> how you pass empty tokens to macros in C and C++.
>

A further thought -- if one really wanted to, this notion of a *nothing*
argument doesn't have to be specific to void types at all. You could simply
state that passing *nothing* is always shorthand for specifying default
construction of a parameter. In that case, void is nothing special at all,
but rather, it's simply a type that is default-constructible, which is why
you can pass *nothing* as an argument for a unary void function. This just
generalizes the idea of a *nothing* argument. In cases where the parameter
type needs to be deduced to T and someone passes *nothing*, then T could
just be specified to be deduced as void.

The only place this generalization of default-construct when passing
*nothing* notion falls apart, that I can think of off-hand, is with
parameters that are reference-to-void (such as set_value of a
std::promise), since a reference isn't default constructible. set_value()
worked prior to generalization because the nothing-ness was a shorthand for
a default-constructed void. It's probably possible to generalize and have
this work, but I'm not sure it's worth it. Just an interesting thought.

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
hu, Jul 30, 2015 at 3:06 PM, Matt Calabrese <span dir=3D"ltr">&lt;<a href=
=3D"mailto:calabrese@google.com" target=3D"_blank">calabrese@google.com</a>=
&gt;</span> wrote:<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 clas=
s=3D"gmail_extra"><div class=3D"gmail_quote"><div><br></div><div>In cases w=
here &quot;void&quot; appears not as the sole parameter type, we can even e=
xtrapolate and do the same thing -- keep in mind that users still need to p=
ass an argument, even if that argument is nothing:</div><div><br></div><div=
>//////////</div><div>// Notice that we can pass &quot;nothing&quot; here. =
This comes naturally from the above rule.</div><div>tuple&lt;int, void, cha=
r, void, void&gt; foo(5, , &#39;a&#39;, , );</div><div>//////////</div><div=
><br></div><div>This type of syntax actually has precedent in C++ already, =
since this is how you pass empty tokens to macros in C and C++.<br></div></=
div></div></div></blockquote><div><br></div><div>A further thought -- if on=
e really wanted to, this notion of a <i>nothing</i> argument doesn&#39;t ha=
ve to be specific to void types at all. You could simply state that passing=
 <i>nothing</i> is always shorthand for specifying default construction of =
a parameter. In that case, void is nothing special at all, but rather, it&#=
39;s simply a type that is default-constructible, which is why you can pass=
 <i>nothing</i>=C2=A0as an argument for a unary void function. This just ge=
neralizes the idea of a <i>nothing</i>=C2=A0argument. In cases where the pa=
rameter type needs to be deduced to T and someone passes <i>nothing</i>, th=
en T could just be specified to be deduced as void.<br></div><div><br></div=
><div>The only place this generalization of default-construct when passing =
<i>nothing</i>=C2=A0notion falls apart, that I can think of off-hand, is wi=
th parameters that are reference-to-void (such as set_value of a std::promi=
se), since a reference isn&#39;t default constructible. set_value() worked =
prior to generalization because the nothing-ness was a shorthand for a defa=
ult-constructed void. It&#39;s probably possible to generalize and have thi=
s work, but I&#39;m not sure it&#39;s worth it. Just an interesting thought=
..=C2=A0</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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a1134af4044b1bd051c1f9e99--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Thu, 30 Jul 2015 16:49:34 -0700
Raw View
On Thursday 30 July 2015 14:17:42 martin.molzer@gmx.de wrote:
> This suddenly also allows dereferencing a void* pointer.
>
> template <typename T, T (*Func)()>
> void h(T *ptr)
> {
>         *ptr = Func();
> }
>
> Should the compiler warn that ptr wasn't used?
>
> Why is that a bad thing? I wouldn't even say that a warning was need, but
> you are right that one has to define the semantics for a void pointer.
> Possibly something like dereferencing a void pointer results in an
> (imaginary) reference to a void value. Asignment doesn't do anything at
> all, thus "it is safe" to do so.
>
> If this was for the sake of generalizing generic programming methods, I
> would happily try to come up with good stuff.

It's like a pointer to nullptr_t: you don't read from it and you don't write
to it. It's always null.
--
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/.

.


Author: martin.molzer@gmx.de
Date: Thu, 30 Jul 2015 17:08:16 -0700 (PDT)
Raw View
------=_Part_72_1201914402.1438301297078
Content-Type: multipart/alternative;
 boundary="----=_Part_73_666042900.1438301297078"

------=_Part_73_666042900.1438301297078
Content-Type: text/plain; charset=UTF-8



> I see no reason to not support all of the comparisons. There's no reason
> to not support <, for instance. Also, void types should be assignable. They
> should be regular types.
>

Sounds reasonable. They should definitly be assignable, although assigning
them should be effectively a no-op.

>
>>    - is "swallowed" when given as an argument to a function. It appears
>>    as if it wasn't given (but the expression giving this void is evaluated).
>>
>> I disagree here. You still should be able to pass void and have them
> really be separate arguments. Consider the following example in generic
> code:
>

But then you'll break forward compatibility because foo() is different to
foo(void), it's just another overload. That wouldn't be favorable, because
it messes with old code.

> Ultimately, if we are to have properly designed void types, they should
not be particularly special. They should just be regular types like most
other (proper) C++.

I have to disagree. To have no problems with the current implementation and
design, all operations directly regarding void have to be resolvable during
compile time. If they wouldn't, that means that they'd carry some data,
which is against the idea of this proposition.
So ultimatly, all operations with void-types, won't induce any kind of new
undefined behaviour, because either the fault can be detected at
compile-time or there is no trace of the operation left during runtime.

>It's like a pointer to nullptr_t: you don't read from it and you don't
write
>to it. It's always null.

Yes to the first sentence, no to the second one. Because void carries no
data, you can't read nor write anything. So one should be able to come up
with a formulation that allows dereferencing a void*, but doesn't allow
writing/reading from it (so it allows operations with a void object - no
reading or writing necessary and also compile-time static)

--

---
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_73_666042900.1438301297078
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><div><div class=3D"gmail_quote"><div>I see no reason to not suppor=
t all of the comparisons. There&#39;s no reason to not support &lt;, for in=
stance. Also, void types should be assignable. They should be regular types=
..</div></div></div></div></blockquote><div>=C2=A0</div><div>Sounds reasonab=
le. They should definitly be assignable, although assigning them should be =
effectively a no-op.<br></div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">=
<div dir=3D"ltr"><div><div class=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"><ul><li>is &quot;swallowed&quot; when given as an arg=
ument to a function. It appears as if it wasn&#39;t given (but the expressi=
on giving this void is evaluated).</li></ul></div></blockquote><div>I disag=
ree here. You still should be able to pass void and have them really be sep=
arate arguments. Consider the following example in generic code:</div></div=
></div></div></blockquote><div class=3D"gmail_quote"><br>But then you&#39;l=
l break forward compatibility because foo() is different to foo(void), it&#=
39;s just another overload. That wouldn&#39;t be favorable, because it mess=
es with old code. <br><br><div>&gt; Ultimately, if we are to have properly =
designed void types, they should not be particularly special. They should j=
ust be regular types like most other (proper) C++.<br><br>I have to disagre=
e. To have no problems with the current implementation and design, all oper=
ations directly regarding void have to be resolvable during compile time. I=
f they wouldn&#39;t, that means that they&#39;d carry some data, which is a=
gainst the idea of this proposition.<br>So ultimatly, all operations with v=
oid-types, won&#39;t induce any kind of new undefined behaviour, because ei=
ther the fault can be detected at compile-time or there is no trace of the =
operation left during runtime.<br><br>&gt;It&#39;s like a pointer to nullpt=
r_t: you don&#39;t read from it and you don&#39;t write=20
<br>&gt;to it. It&#39;s always null.<br><br>Yes to the first sentence, no t=
o the second one. Because void carries no data, you can&#39;t read nor writ=
e anything. So one should be able to come up with a formulation that allows=
 dereferencing a void*, but doesn&#39;t allow writing/reading from it (so i=
t allows operations with a void object - no reading or writing necessary an=
d also compile-time static)<br><br></div></div><blockquote class=3D"gmail_q=
uote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;pad=
ding-left: 1ex;">
</blockquote></div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_73_666042900.1438301297078--
------=_Part_72_1201914402.1438301297078--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Thu, 30 Jul 2015 17:39:39 -0700
Raw View
--047d7bd7648e1ab10d051c210e6e
Content-Type: text/plain; charset=UTF-8

On Thu, Jul 30, 2015 at 5:08 PM, <martin.molzer@gmx.de> wrote:

>
> I see no reason to not support all of the comparisons. There's no reason
>> to not support <, for instance. Also, void types should be assignable. They
>> should be regular types.
>>
>
> Sounds reasonable. They should definitly be assignable, although assigning
> them should be effectively a no-op.
>
>>
>>>    - is "swallowed" when given as an argument to a function. It appears
>>>    as if it wasn't given (but the expression giving this void is evaluated).
>>>
>>> I disagree here. You still should be able to pass void and have them
>> really be separate arguments. Consider the following example in generic
>> code:
>>
>
> But then you'll break forward compatibility because foo() is different to
> foo(void), it's just another overload. That wouldn't be favorable, because
> it messes with old code.
>

Not really. Regarding the differing function types, I address that in a
later reply. Regarding if two overloads exist -- one where it's a nullary
function and one where it's a unary void function, you could just state
that the nullary function is a better match if you pass *nothing* whereas a
unary function taking a void parameter is a better match if you actually
pass in an expression of type void. There might be more to it than this,
but I don't see a fundamental blocker here.


> > Ultimately, if we are to have properly designed void types, they should
> not be particularly special. They should just be regular types like most
> other (proper) C++.
>
> I have to disagree. To have no problems with the current implementation
> and design, all operations directly regarding void have to be resolvable
> during compile time. If they wouldn't, that means that they'd carry some
> data, which is against the idea of this proposition.
>

I'm not sure what you are disagreeing with. As far as I can tell we are in
agreement. Can you clarify with an example of where you feel we disagree? A
void type wouldn't carry any data at all as it would be logically
stateless. A stateless type is still a regular type even though most of its
operations are no-ops. The only thing a void instance needs is a unique
address with respect to other voids if the address is ever observed, which
is just a (sometimes unfortunate) implication when dealing with types in
C++. All of the operations, such as copying and assigning are no-ops or
yield compile-time constants (comparisons). All operations are also
constexpr, etc. None of this goes against any of what you're proposing as
far as I can see. The way to get it easy to use in generic code is to
simply have it be a regular type, with the only differences being syntactic
sugar and/or *additional* functionality.


> So ultimatly, all operations with void-types, won't induce any kind of new
> undefined behaviour, because either the fault can be detected at
> compile-time or there is no trace of the operation left during runtime.
>

Can you give an example of what you mean? How would this introduce "new
undefined behavior." There shouldn't be anything new here at all regarding
undefined behavior, since void would just be like any other C++ type. There
shouldn't be anything special about it at all. It should just be a
stateless type.

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
hu, Jul 30, 2015 at 5:08 PM,  <span dir=3D"ltr">&lt;<a href=3D"mailto:marti=
n.molzer@gmx.de" target=3D"_blank">martin.molzer@gmx.de</a>&gt;</span> wrot=
e:<br><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"><span class=3D""><br>=
<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;borde=
r-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><div class=3D=
"gmail_quote"><div>I see no reason to not support all of the comparisons. T=
here&#39;s no reason to not support &lt;, for instance. Also, void types sh=
ould be assignable. They should be regular types.</div></div></div></div></=
blockquote><div>=C2=A0</div></span><div>Sounds reasonable. They should defi=
nitly be assignable, although assigning them should be effectively a no-op.=
<br></div><span class=3D""><blockquote class=3D"gmail_quote" style=3D"margi=
n:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><div><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" =
style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><di=
v dir=3D"ltr"><ul><li>is &quot;swallowed&quot; when given as an argument to=
 a function. It appears as if it wasn&#39;t given (but the expression givin=
g this void is evaluated).</li></ul></div></blockquote><div>I disagree here=
.. You still should be able to pass void and have them really be separate ar=
guments. Consider the following example in generic code:</div></div></div><=
/div></blockquote></span><div class=3D"gmail_quote"><br>But then you&#39;ll=
 break forward compatibility because foo() is different to foo(void), it&#3=
9;s just another overload. That wouldn&#39;t be favorable, because it messe=
s with old code. <br></div></div></blockquote><div><br></div><div>Not reall=
y. Regarding the differing function types, I address that in a later reply.=
 Regarding if two overloads exist -- one where it&#39;s a nullary function =
and one where it&#39;s a unary void function, you could just state that the=
 nullary function is a better match if you pass <i>nothing</i>=C2=A0whereas=
 a unary function taking a void parameter is a better match if you actually=
 pass in an expression of type void. There might be more to it than this, b=
ut I don&#39;t see a fundamental blocker here.</div><div>=C2=A0</div><block=
quote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc=
 solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_quote"><div><=
span class=3D"">&gt; Ultimately, if we are to have properly designed void t=
ypes, they should not be particularly special. They should just be regular =
types like most other (proper) C++.<br><br></span>I have to disagree. To ha=
ve no problems with the current implementation and design, all operations d=
irectly regarding void have to be resolvable during compile time. If they w=
ouldn&#39;t, that means that they&#39;d carry some data, which is against t=
he idea of this proposition.<br></div></div></div></blockquote><div><br></d=
iv><div>I&#39;m not sure what you are disagreeing with. As far as I can tel=
l we are in agreement. Can you clarify with an example of where you feel we=
 disagree? A void type wouldn&#39;t carry any data at all as it would be lo=
gically stateless. A stateless type is still a regular type even though mos=
t of its operations are no-ops. The only thing a void instance needs is a u=
nique address with respect to other voids if the address is ever observed, =
which is just a (sometimes unfortunate) implication when dealing with types=
 in C++. All of the operations, such as copying and assigning are no-ops or=
 yield compile-time constants (comparisons). All operations are also conste=
xpr, etc. None of this goes against any of what you&#39;re proposing as far=
 as I can see. The way to get it easy to use in generic code is to simply h=
ave it be a regular type, with the only differences being syntactic sugar a=
nd/or <i>additional</i>=C2=A0functionality.</div><div>=C2=A0</div><blockquo=
te class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc so=
lid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_quote"><div>So u=
ltimatly, all operations with void-types, won&#39;t induce any kind of new =
undefined behaviour, because either the fault can be detected at compile-ti=
me or there is no trace of the operation left during runtime.</div></div></=
div></blockquote><div><br></div><div>Can you give an example of what you me=
an? How would this introduce &quot;new undefined behavior.&quot; There shou=
ldn&#39;t be anything new here at all regarding undefined behavior, since v=
oid would just be like any other C++ type. There shouldn&#39;t be anything =
special about it at all. It should just be a stateless type.</div></div></d=
iv></div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--047d7bd7648e1ab10d051c210e6e--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Thu, 30 Jul 2015 17:54:12 -0700
Raw View
--089e0149c77a1db99c051c214207
Content-Type: text/plain; charset=UTF-8

On Thu, Jul 30, 2015 at 5:39 PM, Matt Calabrese <calabrese@google.com>
wrote:
>
> Can you give an example of what you mean? How would this introduce "new
> undefined behavior." There shouldn't be anything new here at all regarding
> undefined behavior, since void would just be like any other C++ type. There
> shouldn't be anything special about it at all. It should just be a
> stateless type.
>

To be clear, this is (effectively) all that the complete void type would
be, in my opinion:

//////////
struct void {};
constexpr bool operator ==(void, void) noexcept { return true; }
constexpr bool operator <=(void, void) noexcept { return true; }
constexpr bool operator >=(void, void) noexcept { return true; }
constexpr bool operator !=(void, void) noexcept { return false; }
constexpr bool operator <(void, void) noexcept { return false; }
constexpr bool operator >(void, void) noexcept { return false; }
//////////

And that is that. Everything else would just effectively syntactic sugar,
such as an empty argument meaning "default-constructed-void". There
shouldn't need to be very many changes to the language, and backwards
compatibility can be maintained in the way I described earlier.

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
hu, Jul 30, 2015 at 5:39 PM, Matt Calabrese <span dir=3D"ltr">&lt;<a href=
=3D"mailto:calabrese@google.com" target=3D"_blank">calabrese@google.com</a>=
&gt;</span> wrote:<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 clas=
s=3D"gmail_extra"><div class=3D"gmail_quote"><div>Can you give an example o=
f what you mean? How would this introduce &quot;new undefined behavior.&quo=
t; There shouldn&#39;t be anything new here at all regarding undefined beha=
vior, since void would just be like any other C++ type. There shouldn&#39;t=
 be anything special about it at all. It should just be a stateless type.</=
div></div></div></div>
</blockquote></div><br></div><div class=3D"gmail_extra">To be clear, this i=
s (effectively) all that the complete void type would be, in my opinion:</d=
iv><div class=3D"gmail_extra"><br></div><div class=3D"gmail_extra">////////=
//</div><div class=3D"gmail_extra">struct void {};</div><div class=3D"gmail=
_extra">constexpr bool operator =3D=3D(void, void) noexcept { return true; =
}<br></div><div class=3D"gmail_extra"><div class=3D"gmail_extra">constexpr =
bool operator &lt;=3D(void, void) noexcept { return true; }</div><div class=
=3D"gmail_extra">constexpr bool operator &gt;=3D(void, void) noexcept { ret=
urn true; }</div>constexpr bool operator !=3D(void, void) noexcept { return=
 false; }<div class=3D"gmail_extra">constexpr bool operator &lt;(void, void=
) noexcept { return false; }</div><div class=3D"gmail_extra">constexpr bool=
 operator &gt;(void, void) noexcept { return false; }</div></div><div class=
=3D"gmail_extra">//////////</div><div class=3D"gmail_extra"><br></div><div =
class=3D"gmail_extra">And that is that. Everything else would just effectiv=
ely syntactic sugar, such as an empty argument meaning &quot;default-constr=
ucted-void&quot;. There shouldn&#39;t need to be very many changes to the l=
anguage, and backwards compatibility can be maintained in the way I describ=
ed earlier.</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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--089e0149c77a1db99c051c214207--

.


Author: sean.parent@gmail.com
Date: Thu, 30 Jul 2015 21:50:08 -0700 (PDT)
Raw View
------=_Part_24_324979767.1438318208986
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Since my name was sucked into this - There are many ways the standard tries=
 to avoid 0, I've considered giving a short talk titled "Nothing is Unavoid=
able". For every problem avoided, another is created. I'd like to see as ma=
ny of these repaired as possible. I totally understand that many of these w=
ould break backward compatibility in a number of ways - but making void mod=
el Regular would make writing generic code _so_ much nicer.

empty classes and structs should have sizeof(0) to avoid inefficiencies and=
 compressed pair hacks.
f(void) and f() are two different signatures - one takes a single argument =
of type void, the other takes no arguments.
void* should be a pointer to nothing, not a pointer to anything.
int a[0]; Should be perfectly legal. As should void a[42];
Aliasing rules should only apply to objects with size. Two objects of zero =
size can share the same address.
void x; should be legal, as should void x =3D f() when x returns void.

Babylonians "discovered" zero some 2400 years ago - but it took nearly 2000=
 years to find it's way into common use. Zero makes us uncomfortable becaus=
e it is a discontinuity, but it should be dealt with directly instead of tr=
ying to hide or avoid it.

--=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_24_324979767.1438318208986--

.


Author: Jared Grubb <jared.grubb@gmail.com>
Date: Thu, 30 Jul 2015 22:16:59 -0700 (PDT)
Raw View
------=_Part_347_1495811298.1438319820252
Content-Type: multipart/alternative;
 boundary="----=_Part_348_1338466852.1438319820253"

------=_Part_348_1338466852.1438319820253
Content-Type: text/plain; charset=UTF-8

I actually had a wish for this a while back. I had code that was doing
something like JSON visitation:

    auto visit_string(VisitorType& visitor) {
       return visitor(stuff...);
    }

and then had another member like this:

    auto visit_array(VisitorType& visitor) {
       ++this->indentation;
       auto result = visitor(stuff...);
       --this->indentation;
       return result;
    }

The first one works with visitors that return 'void', but the second one
does not compile -- even though it's conceptually the same thing.

I think others are making good arguments for and against but just wanted to
chime in and express my support.

Jared

P.S. I did use an RAII-style thing in the end to work around this issue,
but I would still prefer the above form.


On Thursday, July 30, 2015 at 1:49:44 PM UTC-7, martin...@gmx.de wrote:
>
> Currently, declaring a variable as void is forbidden. That makes sense but
> restricts some cases of generic programming.
>
> The intent is, to allow variables of type void but make them carry no
> actual data.
>
> Consider:
>
> template<typename R, typename Q, typename... A>
> Q concat(R (*fn)(A...), Q (*fn2)(R), A&&... a)
> {
>   R result = fn(a...);
>   return fn2(result);
> }
>
> int convert(float f)
> {
>   return f;
> }
>
> void print(int a)
> {
>   std::cout << a;
> }
>
> auto convert_and_print = std::bind(concat<int, void, float>, convert,
> print, std::placeholders::_1);
> convert_and_print(3.5f);
>
> This method can be used, combined with bind to combine two methods into
> one. But it fails, when the return type of the first function is void. Why
> would we need that, well consider
>
> void print(int a)
> {
>   std::cout << a;
> }
> void printline()
> {
>   std::cout << std::endl;
> }
> //auto print_with_ln = std::bind(concat<void, void, int>, print,
> printline, std::placeholders::_1);
> // Fails horribly at the moment
>
> I consider this a bad design by the language and thus propose the
> following:
>
> A variable of type void
>
>    - occupies no space (sizeof(void) == 0)
>    - holds no value and can not be converted to any other type.
>    - has an alignment of 1 (aligned to a storage unit boundary).
>    - defines the following operators
>       - defines no other operators but == and !=
>       - compares equal to all other void variables (up to discussion)
>    - is "swallowed" when given as an argument to a function. It appears
>    as if it wasn't given (but the expression giving this void is evaluated).
>
>
> Certainly, there is a second point we have to take care of.
>
> A function with the signature R(A..., B...) also has the signature R(A...,
> void, B...) with typename R and typename...A, typename... B. This is to be
> able to bind no-args functions as a function accepting a void argument, and
> so forth.
>
> With this the example print_with_ln would certainly compile and execute.
>
>  -- WE
>

--

---
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_348_1338466852.1438319820253
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I actually had a wish for this a while back. I had code th=
at was doing something like JSON visitation:<br><br>=C2=A0=C2=A0=C2=A0 auto=
 visit_string(VisitorType&amp; visitor) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 return visitor(stuff...);<br>=C2=A0=C2=A0=C2=A0 }<br><br>and then ha=
d another member like this: <br><br>=C2=A0=C2=A0=C2=A0 auto visit_array(Vis=
itorType&amp; visitor) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ++this-&gt=
;indentation;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto result =3D visit=
or(stuff...);<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 --this-&gt;indentatio=
n;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return result;<br>=C2=A0=C2=A0=
=C2=A0 }<br><br>The first one works with visitors that return &#39;void&#39=
;, but the second one does not compile -- even though it&#39;s conceptually=
 the same thing.<br><br>I think others are making good arguments for and ag=
ainst but just wanted to chime in and express my support.<br><br>Jared<br><=
br>P.S. I did use an RAII-style thing in the end to work around this issue,=
 but I would still prefer the above form.<br><br><br>On Thursday, July 30, =
2015 at 1:49:44 PM UTC-7, martin...@gmx.de wrote:<blockquote class=3D"gmail=
_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;p=
adding-left: 1ex;"><div dir=3D"ltr">Currently, declaring a variable as void=
 is forbidden. That makes sense but restricts some cases of generic program=
ming.<br><br>The intent is, to allow variables of type void but make them c=
arry no actual data.<br><br>Consider:<br><br><div style=3D"background-color=
:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-w=
idth:1px;word-wrap:break-word"><code><div><span style=3D"color:#008">templa=
te</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">t=
ypename</span><span style=3D"color:#000"> R</span><span style=3D"color:#660=
">,</span><span style=3D"color:#000"> </span><span style=3D"color:#008">typ=
ename</span><span style=3D"color:#000"> Q</span><span style=3D"color:#660">=
,</span><span style=3D"color:#000"> </span><span style=3D"color:#008">typen=
ame</span><span style=3D"color:#660">...</span><span style=3D"color:#000"> =
A</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"><b=
r>Q concat</span><span style=3D"color:#660">(</span><span style=3D"color:#0=
00">R </span><span style=3D"color:#660">(*</span><span style=3D"color:#000"=
>fn</span><span style=3D"color:#660">)(</span><span style=3D"color:#000">A<=
/span><span style=3D"color:#660">...),</span><span style=3D"color:#000"> Q =
</span><span style=3D"color:#660">(*</span><span style=3D"color:#000">fn2</=
span><span style=3D"color:#660">)(</span><span style=3D"color:#000">R</span=
><span style=3D"color:#660">),</span><span style=3D"color:#000"> A</span><s=
pan style=3D"color:#660">&amp;&amp;...</span><span style=3D"color:#000"> a<=
/span><span style=3D"color:#660">)</span><span style=3D"color:#000"><br></s=
pan><span style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=
=A0 R result </span><span style=3D"color:#660">=3D</span><span style=3D"col=
or:#000"> fn</span><span style=3D"color:#660">(</span><span style=3D"color:=
#000">a</span><span style=3D"color:#660">...);</span><span style=3D"color:#=
000"><br>=C2=A0 </span><span style=3D"color:#008">return</span><span style=
=3D"color:#000"> fn2</span><span style=3D"color:#660">(</span><span style=
=3D"color:#000">result</span><span style=3D"color:#660">);</span><span styl=
e=3D"color:#000"><br></span><span style=3D"color:#660">}</span><span style=
=3D"color:#000"><br><br></span><span style=3D"color:#008">int</span><span s=
tyle=3D"color:#000"> convert</span><span style=3D"color:#660">(</span><span=
 style=3D"color:#008">float</span><span style=3D"color:#000"> f</span><span=
 style=3D"color:#660">)</span><span style=3D"color:#000"><br></span><span s=
tyle=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 </span><s=
pan style=3D"color:#008">return</span><span style=3D"color:#000"> f</span><=
span style=3D"color:#660">;</span><span style=3D"color:#000"><br></span><sp=
an style=3D"color:#660">}</span><span style=3D"color:#000"><br><br></span><=
span style=3D"color:#008">void</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#008">print</span><span style=3D"color:#660">(</span><spa=
n style=3D"color:#008">int</span><span style=3D"color:#000"> a</span><span =
style=3D"color:#660">)</span><span style=3D"color:#000"><br></span><span st=
yle=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 std</span>=
<span style=3D"color:#660">::</span><span style=3D"color:#000">cout </span>=
<span style=3D"color:#660">&lt;&lt;</span><span style=3D"color:#000"> a</sp=
an><span style=3D"color:#660">;</span><span style=3D"color:#000"><br></span=
><span style=3D"color:#660">}</span><span style=3D"color:#000"><br><br></sp=
an><span style=3D"color:#008">auto</span><span style=3D"color:#000"> conver=
t_and_print </span><span style=3D"color:#660">=3D</span><span style=3D"colo=
r:#000"> std</span><span style=3D"color:#660">::</span><span style=3D"color=
:#000">bind</span><span style=3D"color:#660">(</span><span style=3D"color:#=
000">concat</span><span style=3D"color:#660">&lt;</span><span style=3D"colo=
r:#008">int</span><span style=3D"color:#660">,</span><span style=3D"color:#=
000"> </span><span style=3D"color:#008">void</span><span style=3D"color:#66=
0">,</span><span style=3D"color:#000"> </span><span style=3D"color:#008">fl=
oat</span><span style=3D"color:#660">&gt;,</span><span style=3D"color:#000"=
> convert</span><span style=3D"color:#660">,</span><span style=3D"color:#00=
0"> </span><span style=3D"color:#008">print</span><span style=3D"color:#660=
">,</span><span style=3D"color:#000"> std</span><span style=3D"color:#660">=
::</span><span style=3D"color:#000">placeholders</span><span style=3D"color=
:#660">::</span><span style=3D"color:#000">_1</span><span style=3D"color:#6=
60">);</span><span style=3D"color:#000"><br>convert_and_print</span><span s=
tyle=3D"color:#660">(</span><span style=3D"color:#066">3.5f</span><span sty=
le=3D"color:#660">);</span><span style=3D"color:#000"><br></span></div></co=
de></div><br>This method can be used, combined with bind to combine two met=
hods into one. But it fails, when the return type of the first function is =
void. Why would we need that, well consider<br><br><div style=3D"background=
-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;bo=
rder-width:1px;word-wrap:break-word"><code><div><span style=3D"color:#008">=
void</span><span style=3D"color:#000"> </span><span style=3D"color:#008">pr=
int</span><span style=3D"color:#660">(</span><span style=3D"color:#008">int=
</span><span style=3D"color:#000"> a</span><span style=3D"color:#660">)</sp=
an><span style=3D"color:#000"><br></span><span style=3D"color:#660">{</span=
><span style=3D"color:#000"><br>=C2=A0 std</span><span style=3D"color:#660"=
>::</span><span style=3D"color:#000">cout </span><span style=3D"color:#660"=
>&lt;&lt;</span><span style=3D"color:#000"> a</span><span style=3D"color:#6=
60">;</span><span style=3D"color:#000"><br></span><span style=3D"color:#660=
">}</span><span style=3D"color:#000"><br></span><span style=3D"color:#008">=
void</span><span style=3D"color:#000"> printline</span><span style=3D"color=
:#660">()</span><span style=3D"color:#000"><br></span><span style=3D"color:=
#660">{</span><span style=3D"color:#000"><br>=C2=A0 std</span><span style=
=3D"color:#660">::</span><span style=3D"color:#000">cout </span><span style=
=3D"color:#660">&lt;&lt;</span><span style=3D"color:#000"> std</span><span =
style=3D"color:#660">::</span><span style=3D"color:#000">endl</span><span s=
tyle=3D"color:#660">;</span><span style=3D"color:#000"><br></span><span sty=
le=3D"color:#660">}</span><span style=3D"color:#000"><br></span><span style=
=3D"color:#800">//auto print_with_ln =3D std::bind(concat&lt;void, void, in=
t&gt;, print, printline, std::placeholders::_1);</span><span style=3D"color=
:#000"><br></span><span style=3D"color:#800">// Fails horribly at the momen=
t</span><span style=3D"color:#000"><br></span></div></code></div><br>I cons=
ider this a bad design by the language and thus propose the following:<br><=
br>A variable of type void<br><ul><li>occupies no space (sizeof(void) =3D=
=3D 0)</li><li>holds no value and can not be converted to any other type.</=
li><li>has an alignment of 1 (aligned to a storage unit boundary).</li><li>=
defines the following operators</li><ul><li>defines no other operators but =
=3D=3D and !=3D</li><li>compares equal to all other void variables (up to d=
iscussion)</li></ul><li>is &quot;swallowed&quot; when given as an argument =
to a function. It appears as if it wasn&#39;t given (but the expression giv=
ing this void is evaluated).</li></ul><br>Certainly, there is a second poin=
t we have to take care of.<br><br>A function with the signature R(A..., B..=
..) also has the signature R(A..., void, B...) with typename R and typename.=
...A, typename... B. This is to be able to bind no-args functions as a funct=
ion accepting a void argument, and so forth.<br><br>With this the example p=
rint_with_ln would certainly compile and execute.<br><br>=C2=A0-- WE<br></d=
iv></blockquote></div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_348_1338466852.1438319820253--
------=_Part_347_1495811298.1438319820252--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Thu, 30 Jul 2015 23:04:46 -0700
Raw View
--001a1134fd40d4e9d6051c25986f
Content-Type: text/plain; charset=UTF-8

On Thu, Jul 30, 2015 at 9:50 PM, <sean.parent@gmail.com> wrote:

> Since my name was sucked into this


Thanks for replying, Sean!


> - There are many ways the standard tries to avoid 0, I've considered
> giving a short talk titled "Nothing is Unavoidable". For every problem
> avoided, another is created. I'd like to see as many of these repaired as
> possible. I totally understand that many of these would break backward
> compatibility in a number of ways - but making void model Regular would
> make writing generic code _so_ much nicer.


Agreed, and please give that talk.

empty classes and structs should have sizeof(0) to avoid inefficiencies and
> compressed pair hacks.
>

I agree, though I think this is the only thing that would be considerably
difficult to actually change in the language, as user-code can and likely
does depend on objects of the same type having different addresses,
sometimes in subtle ways that would be difficult to gleen. Even something
as common and fundamental as using a pointer as an iterator into an array
breaks down once you have empty types. There are unfortunately common
assumptions and uses of addresses in existence that would break if we had
size 0 objects. IMO, getting them to be size 0, specifically, just seems
like a much harder thing to fix, and the gains aren't that much when
compared to the benefits of simply having void be a regular type.

f(void) and f() are two different signatures - one takes a single argument
> of type void, the other takes no arguments.
>

Ideally I want this, but it means that existing code that declares
foo(void) now changes meaning. I know you favor not worrying about breaking
code, but realistically this can have pretty far-reaching ramifications. In
practice it's ABI breaking and things like void foo(); void foo(void) {}
would no longer refer to the same functions. It shouldn't hurt generic code
to just say that foo(void) is unary if and only if "void" is actually a
typedef of void or dependent on a template parameter. As long as
invocations of a nullary function and a function taking a single void
parameter work the same way (perhaps only differing in which is a better
match when passing in nothing), I think this has the same affect without
being anymore difficult to write generic code.


> void* should be a pointer to nothing, not a pointer to anything.
>

+1 though would this require doing anything at the language level other
than removing implicit casts to void and requiring the explicit cast to be
reinterpret_cast rather than static_cast? The language already allows
converting pointers between alignment-compatible types, so unless that
changes, too, this change seems not too tough. It's more of a change in how
people should think about void* than how it's represented at the core
language level.

int a[0]; Should be perfectly legal. As should void a[42];
>

+1 FWIW this at least already works for std::array and dynamically
allocated arrays.


> Aliasing rules should only apply to objects with size. Two objects of zero
> size can share the same address.
>

Again, I agree on principle, but I think the ramifications of this are
probably too much, since existing types that are empty could all of a
sudden have properties changed that could break code in really subtle ways.
The only way I see something like this actually getting into the language
is if when you declare a potentially-empty type, you'd do so in a way that
explicitly permits the type to actually be size 0 and have modern aliasing
rules. Of course, in new code you'd probably *always* want to declare every
one of your types that way, so that sucks. This just seems like the hardest
part of all of this to actually fix in the language. Everything else seems
feasible and not even very controversial.

void x; should be legal, as should void x = f() when x returns void.
>

+1


> Babylonians "discovered" zero some 2400 years ago - but it took nearly
> 2000 years to find it's way into common use. Zero makes us uncomfortable
> because it is a discontinuity, but it should be dealt with directly instead
> of trying to hide or avoid it.


Give your talk! I feel like most people who do generic programming should
understand this, but it's not always immediately clear for some reason.

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
hu, Jul 30, 2015 at 9:50 PM,  <span dir=3D"ltr">&lt;<a href=3D"mailto:sean.=
parent@gmail.com" target=3D"_blank">sean.parent@gmail.com</a>&gt;</span> wr=
ote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border=
-left:1px #ccc solid;padding-left:1ex">Since my name was sucked into this</=
blockquote><div><br></div><div>Thanks for replying, Sean!</div><div>=C2=A0<=
/div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-le=
ft:1px #ccc solid;padding-left:1ex"> - There are many ways the standard tri=
es to avoid 0, I&#39;ve considered giving a short talk titled &quot;Nothing=
 is Unavoidable&quot;. For every problem avoided, another is created. I&#39=
;d like to see as many of these repaired as possible. I totally understand =
that many of these would break backward compatibility in a number of ways -=
 but making void model Regular would make writing generic code _so_ much ni=
cer.</blockquote><div><br></div><div>Agreed, and please give that talk.</di=
v><div><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8=
ex;border-left:1px #ccc solid;padding-left:1ex">empty classes and structs s=
hould have sizeof(0) to avoid inefficiencies and compressed pair hacks.<br>=
</blockquote><div><br></div><div>I agree, though I think this is the only t=
hing that would be considerably difficult to actually change in the languag=
e, as user-code can and likely does depend on objects of the same type havi=
ng different addresses, sometimes in subtle ways that would be difficult to=
 gleen. Even something as common and fundamental as using a pointer as an i=
terator into an array breaks down once you have empty types. There are unfo=
rtunately common assumptions and uses of addresses in existence that would =
break if we had size 0 objects. IMO, getting them to be size 0, specificall=
y, just seems like a much harder thing to fix, and the gains aren&#39;t tha=
t much when compared to the benefits of simply having void be a regular typ=
e.=C2=A0</div><div><br></div><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
f(void) and f() are two different signatures - one takes a single argument =
of type void, the other takes no arguments.<br></blockquote><div><br></div>=
<div>Ideally I want this, but it means that existing code that declares foo=
(void) now changes meaning. I know you favor not worrying about breaking co=
de, but realistically this can have pretty far-reaching ramifications. In p=
ractice it&#39;s ABI breaking and things like void foo(); void foo(void) {}=
 would no longer refer to the same functions. It shouldn&#39;t hurt generic=
 code to just say that foo(void) is unary if and only if &quot;void&quot; i=
s actually a typedef of void or dependent on a template parameter. As long =
as invocations of a nullary function and a function taking a single void pa=
rameter work the same way (perhaps only differing in which is a better matc=
h when passing in nothing), I think this has the same affect without being =
anymore difficult to write generic code.</div><div>=C2=A0</div><blockquote =
class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid=
;padding-left:1ex">
void* should be a pointer to nothing, not a pointer to anything.<br></block=
quote><div><br></div><div>+1 though would this require doing anything at th=
e language level other than removing implicit casts to void and requiring t=
he explicit cast to be reinterpret_cast rather than static_cast? The langua=
ge already allows converting pointers between alignment-compatible types, s=
o unless that changes, too, this change seems not too tough. It&#39;s more =
of a change in how people should think about void* than how it&#39;s repres=
ented at the core language level.</div><div><br></div><blockquote class=3D"=
gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-=
left:1ex">
int a[0]; Should be perfectly legal. As should void a[42];<br></blockquote>=
<div><br></div><div>+1 FWIW this at least already works for std::array and =
dynamically allocated arrays.</div><div>=C2=A0</div><blockquote class=3D"gm=
ail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-le=
ft:1ex">
Aliasing rules should only apply to objects with size. Two objects of zero =
size can share the same address.<br></blockquote><div><br></div><div>Again,=
 I agree on principle, but I think the ramifications of this are probably t=
oo much, since existing types that are empty could all of a sudden have pro=
perties changed that could break code in really subtle ways. The only way I=
 see something like this actually getting into the language is if when you =
declare a potentially-empty type, you&#39;d do so in a way that explicitly =
permits the type to actually be size 0 and have modern aliasing rules. Of c=
ourse, in new code you&#39;d probably <i>always</i> want to declare every o=
ne of your types that way, so that sucks. This just seems like the hardest =
part of all of this to actually fix in the language. Everything else seems =
feasible and not even very controversial.</div><div><br></div><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;=
padding-left:1ex">
void x; should be legal, as should void x =3D f() when x returns void.<br><=
/blockquote><div><br></div><div>+1</div><div>=C2=A0</div><blockquote class=
=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd=
ing-left:1ex">Babylonians &quot;discovered&quot; zero some 2400 years ago -=
 but it took nearly 2000 years to find it&#39;s way into common use. Zero m=
akes us uncomfortable because it is a discontinuity, but it should be dealt=
 with directly instead of trying to hide or avoid it.</blockquote><div><br>=
</div><div>Give your talk! I feel like most people who do generic programmi=
ng should understand this, but it&#39;s not always immediately clear for so=
me reason.</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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a1134fd40d4e9d6051c25986f--

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Fri, 31 Jul 2015 10:04:18 -0400
Raw View
On 2015-07-30 18:06, 'Matt Calabrese' via ISO C++ Standard - Future
Proposals wrote:
> Ultimately, if we are to have properly designed void types, they should not
> be particularly special. They should just be regular types like most other
> (proper) C++.

Food for thought:

Python has no concept of functions that do not have return values; a
function that does not explicitly return, or just says 'return', returns
None.

So this is legal:

  def foo():
    return

  a = foo()
  # 'a' has value 'None'

....but this is not:

  def foo():
    return

  foo(None) # error, 'foo' takes 0 arguments, given 1
  foo(foo()) # error, 'foo' takes 0 arguments, given 1

--
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: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Fri, 31 Jul 2015 11:41:34 -0700
Raw View
--001a1134fd40578e4c051c302bd4
Content-Type: text/plain; charset=UTF-8

On Fri, Jul 31, 2015 at 7:04 AM, Matthew Woehlke <mwoehlke.floss@gmail.com>
wrote:
>
> Food for thought:
>
> Python has no concept of functions that do not have return values; a
> function that does not explicitly return, or just says 'return', returns
> None.
>
> So this is legal:
>
>   def foo():
>     return
>
>   a = foo()
>   # 'a' has value 'None'
>
> ...but this is not:
>
>   def foo():
>     return
>
>   foo(None) # error, 'foo' takes 0 arguments, given 1
>   foo(foo()) # error, 'foo' takes 0 arguments, given 1
>

Yeah. I think if we were starting from scratch, we would want invoking a
nullary function with the result of a function that returns void to be a
compile error. Only a function that takes void as a parameter should be
able to be passed an expression that result in void (no different from
other types, void just happens to be a stateless type). The only reason we
probably should allow invoking a nullary function with an expression that
yields void is because it means code doesn't have to be rewritten in order
for people to take advantage of this (for instance, code like the
promise<void> specialization doesn't have to change in order for people to
pass in the result of a function call returning void to set_value()). Then
again, maybe that's not something to worry about and we just allow code to
break here in order to force people to update their code (which usually
means simplify their code). It also implies, imo, that the changes
regarding void should impact library and not just core (we'd be more
obligated to remove the promise<void> specialization, which may be a good
thing anyway).

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On F=
ri, Jul 31, 2015 at 7:04 AM, Matthew Woehlke <span dir=3D"ltr">&lt;<a href=
=3D"mailto:mwoehlke.floss@gmail.com" target=3D"_blank">mwoehlke.floss@gmail=
..com</a>&gt;</span> wrote:<blockquote class=3D"gmail_quote" style=3D"margin=
:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Food for thought:<=
br>
<br>
Python has no concept of functions that do not have return values; a<br>
function that does not explicitly return, or just says &#39;return&#39;, re=
turns<br>
None.<br>
<br>
So this is legal:<br>
<br>
=C2=A0 def foo():<br>
=C2=A0 =C2=A0 return<br>
<br>
=C2=A0 a =3D foo()<br>
=C2=A0 # &#39;a&#39; has value &#39;None&#39;<br>
<br>
....but this is not:<br>
<br>
=C2=A0 def foo():<br>
=C2=A0 =C2=A0 return<br>
<br>
=C2=A0 foo(None) # error, &#39;foo&#39; takes 0 arguments, given 1<br>
=C2=A0 foo(foo()) # error, &#39;foo&#39; takes 0 arguments, given 1<br></bl=
ockquote><div><br></div><div>Yeah. I think if we were starting from scratch=
, we would want invoking a nullary function with the result of a function t=
hat returns void to be a compile error. Only a function that takes void as =
a parameter should be able to be passed an expression that result in void (=
no different from other types, void just happens to be a stateless type). T=
he only reason we probably should allow invoking a nullary function with an=
 expression that yields void is because it means code doesn&#39;t have to b=
e rewritten in order for people to take advantage of this (for instance, co=
de like the promise&lt;void&gt; specialization doesn&#39;t have to change i=
n order for people to pass in the result of a function call returning void =
to set_value()). Then again, maybe that&#39;s not something to worry about =
and we just allow code to break here in order to force people to update the=
ir code (which usually means simplify their code). It also implies, imo, th=
at the changes regarding void should impact library and not just core (we&#=
39;d be more obligated to remove the promise&lt;void&gt; specialization, wh=
ich may be a good thing anyway).</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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a1134fd40578e4c051c302bd4--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Fri, 31 Jul 2015 11:44:05 -0700
Raw View
--089e0149c77a549e00051c30342d
Content-Type: text/plain; charset=UTF-8

On Fri, Jul 31, 2015 at 11:41 AM, Matt Calabrese <calabrese@google.com>
wrote:

> Then again, maybe that's not something to worry about and we just allow
> code to break here in order to force people to update their code (which
> usually means simplify their code).
>

I guess "break" is poor phrasing here. It's more just that they wouldn't be
able to take advantage of passing void without making changes to their
code.

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On F=
ri, Jul 31, 2015 at 11:41 AM, Matt Calabrese <span dir=3D"ltr">&lt;<a href=
=3D"mailto:calabrese@google.com" target=3D"_blank">calabrese@google.com</a>=
&gt;</span> wrote:<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"><div =
class=3D"gmail_extra"><div class=3D"gmail_quote"><div>Then again, maybe tha=
t&#39;s not something to worry about and we just allow code to break here i=
n order to force people to update their code (which usually means simplify =
their code).</div></div></div></div></blockquote><div><br></div><div>I gues=
s &quot;break&quot; is poor phrasing here. It&#39;s more just that they wou=
ldn&#39;t be able to take advantage of passing void without making changes =
to their code.=C2=A0</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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--089e0149c77a549e00051c30342d--

.


Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Date: Sat, 1 Aug 2015 11:40:07 -0700 (PDT)
Raw View
------=_Part_646_372062841.1438454407996
Content-Type: multipart/alternative;
 boundary="----=_Part_647_458626771.1438454407997"

------=_Part_647_458626771.1438454407997
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Thursday, July 30, 2015 at 1:49:44 PM UTC-7, martin...@gmx.de wrote:
>
> Currently, declaring a variable as void is forbidden. That makes sense bu=
t=20
> restricts some cases of generic programming.
>
> The intent is, to allow variables of type void but make them carry no=20
> actual data.
>

I've wanted this idea for a while, but I think you need to scale back the=
=20
scope of it to just what's *actually* needed *today* for generic=20
programming.
For example, there's no reason to support sizeof(void), because generic=20
code doesn't use that construct =E2=80=94 or if it does, it's already doing=
 crazy=20
things with memory allocation. (Also, there are 100% excellent reasons to=
=20
keep sizeof(void) a SFINAE failure. Suddenly defining it would break a lot=
=20
of existing code.)

Things I've wanted from void variables can be summed up as


    T f(); T g() { return f(); }  // should work even with T=3Dvoid (and it=
=20
does already today!)

    T f();  void g(T);  ... g(f());  // should work even with T=3Dvoid

    struct s { T m; };  // should work even with T=3Dvoid

    T f(); T v =3D f();  // should work even with T=3Dvoid

In other words, we don't need any "operations on void" other than the=20
ability to default-construct "void" variables; to initialize and assign to=
=20
"void" variables (from expressions whose own type is "void"); and to pass a=
=20
single void argument as the parameter to a function taking no arguments.

The ability to pass a single void argument to a function taking no=20
arguments is, I think, the most palatable first step.
(Or second step, if we count void f() { return g(); } as the first step,=20
already taken. A good proposal would do some historical research there into=
=20
why that feature exists.)

There is no need to support "collapsing" void arguments (e.g. the ability=
=20
to write f(((void)1, 2)) as f((void)1, 2)).
There is no need to support arithmetic, relational, or logical operations=
=20
on void operands.
There is no need to define the size or alignment of void objects; being=20
no-ops, they wouldn't participate in class layout anyway.



Consider:
>
> template<typename R, typename Q, typename... A>
> Q concat(R (*fn)(A...), Q (*fn2)(R), A&&... a)
> {
>   R result =3D fn(a...);
>   return fn2(result);
> }
> This method can be used, combined with bind to combine two methods into=
=20
> one. But it fails, when the return type of the first function is void. Wh=
y=20
> would we need that, well consider
>
>
> A variable of type void
>
>    - occupies no space (sizeof(void) =3D=3D 0)
>    - holds no value and can not be converted to any other type.
>    - has an alignment of 1 (aligned to a storage unit boundary).
>    - defines the following operators
>       - defines no other operators but =3D=3D and !=3D
>       - compares equal to all other void variables (up to discussion)
>    - is "swallowed" when given as an argument to a function. It appears=
=20
>    as if it wasn't given (but the expression giving this void is evaluate=
d).
>
>
> Certainly, there is a second point we have to take care of.
>
> A function with the signature R(A..., B...) also has the signature R(A...=
,=20
> void, B...) with typename R and typename...A, typename... B. This is to b=
e=20
> able to bind no-args functions as a function accepting a void argument, a=
nd=20
> so forth.
>
> With this the example print_with_ln would certainly compile and execute.
>
>  -- WE
>

--=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_647_458626771.1438454407997
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Thursday, July 30, 2015 at 1:49:44 PM UTC-7, martin...@=
gmx.de wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">=
Currently, declaring a variable as void is forbidden. That makes sense but =
restricts some cases of generic programming.<br><br>The intent is, to allow=
 variables of type void but make them carry no actual data.<br></div></bloc=
kquote><div><br></div><div>I&#39;ve wanted this idea for a while, but I thi=
nk you need to scale back the scope of it to just what&#39;s <i>actually</i=
> needed <i>today</i> for generic programming.</div><div>For example, there=
&#39;s no reason to support sizeof(void), because generic code doesn&#39;t =
use that construct =E2=80=94 or if it does, it&#39;s already doing crazy th=
ings with memory allocation. (Also, there are 100% excellent reasons to kee=
p sizeof(void) a SFINAE failure. Suddenly defining it would break a lot of =
existing code.)</div><div><br></div><div>Things I&#39;ve wanted from void v=
ariables can be summed up as</div><div><br></div><div><br></div><div>=C2=A0=
 =C2=A0 T f(); T g() { return f(); } =C2=A0// should work even with T=3Dvoi=
d (and it does already today!)</div><div><br></div><div>=C2=A0 =C2=A0 T f()=
; =C2=A0void g(T); =C2=A0... g(f()); =C2=A0// should work even with T=3Dvoi=
d</div><div><br></div><div><div>=C2=A0 =C2=A0 struct s { T m; }; =C2=A0// s=
hould work even with T=3Dvoid</div></div><div><br></div><div>=C2=A0 =C2=A0 =
T f(); T v =3D f(); =C2=A0// should work even with T=3Dvoid</div><div><br><=
/div><div>In other words, we don&#39;t need any &quot;operations on void&qu=
ot; other than the ability to default-construct &quot;void&quot; variables;=
 to initialize and assign to &quot;void&quot; variables (from expressions w=
hose own type is &quot;void&quot;); and to pass a single void argument as t=
he parameter to a function taking no arguments.</div><div><br></div><div>Th=
e ability to pass a single void argument to a function taking no arguments =
is, I think, the most palatable first step.</div><div>(Or second step, if w=
e count void f() { return g(); } as the first step, already taken. A good p=
roposal would do some historical research there into why that feature exist=
s.)</div><div><br></div><div>There is no need to support &quot;collapsing&q=
uot; void arguments (e.g. the ability to write f(((void)1, 2)) as f((void)1=
, 2)).</div><div>There is no need to support arithmetic, relational, or log=
ical operations on void operands.</div><div>There is no need to define the =
size or alignment of void objects; being no-ops, they wouldn&#39;t particip=
ate in class layout anyway.</div><div><br></div><div><br></div><div><br></d=
iv><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">Consider:<=
br><br><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187=
,187,187);border-style:solid;border-width:1px;word-wrap:break-word"><code><=
div><span style=3D"color:#008">template</span><span style=3D"color:#660">&l=
t;</span><span style=3D"color:#008">typename</span><span style=3D"color:#00=
0"> R</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> =
</span><span style=3D"color:#008">typename</span><span style=3D"color:#000"=
> Q</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> </=
span><span style=3D"color:#008">typename</span><span style=3D"color:#660">.=
...</span><span style=3D"color:#000"> A</span><span style=3D"color:#660">&gt=
;</span><span style=3D"color:#000"><br>Q concat</span><span style=3D"color:=
#660">(</span><span style=3D"color:#000">R </span><span style=3D"color:#660=
">(*</span><span style=3D"color:#000">fn</span><span style=3D"color:#660">)=
(</span><span style=3D"color:#000">A</span><span style=3D"color:#660">...),=
</span><span style=3D"color:#000"> Q </span><span style=3D"color:#660">(*</=
span><span style=3D"color:#000">fn2</span><span style=3D"color:#660">)(</sp=
an><span style=3D"color:#000">R</span><span style=3D"color:#660">),</span><=
span style=3D"color:#000"> A</span><span style=3D"color:#660">&amp;&amp;...=
</span><span style=3D"color:#000"> a</span><span style=3D"color:#660">)</sp=
an><span style=3D"color:#000"><br></span><span style=3D"color:#660">{</span=
><span style=3D"color:#000"><br>=C2=A0 R result </span><span style=3D"color=
:#660">=3D</span><span style=3D"color:#000"> fn</span><span style=3D"color:=
#660">(</span><span style=3D"color:#000">a</span><span style=3D"color:#660"=
>...);</span><span style=3D"color:#000"><br>=C2=A0 </span><span style=3D"co=
lor:#008">return</span><span style=3D"color:#000"> fn2</span><span style=3D=
"color:#660">(</span><span style=3D"color:#000">result</span><span style=3D=
"color:#660">);</span><span style=3D"color:#000"><br></span><span style=3D"=
color:#660">}</span><span style=3D"color:#000"><br></span><span style=3D"ba=
ckground-color: white; font-family: Arial, Helvetica, sans-serif;">This met=
hod can be used, combined with bind to combine two methods into one. But it=
 fails, when the return type of the first function is void. Why would we ne=
ed that, well consider</span><span style=3D"color:#000"><br></span></div></=
code></div><br><div style=3D"background-color:rgb(250,250,250);border-color=
:rgb(187,187,187);border-style:solid;border-width:1px;word-wrap:break-word"=
><code><div><br></div></code></div>A variable of type void<br><ul><li>occup=
ies no space (sizeof(void) =3D=3D 0)</li><li>holds no value and can not be =
converted to any other type.</li><li>has an alignment of 1 (aligned to a st=
orage unit boundary).</li><li>defines the following operators</li><ul><li>d=
efines no other operators but =3D=3D and !=3D</li><li>compares equal to all=
 other void variables (up to discussion)</li></ul><li>is &quot;swallowed&qu=
ot; when given as an argument to a function. It appears as if it wasn&#39;t=
 given (but the expression giving this void is evaluated).</li></ul><br>Cer=
tainly, there is a second point we have to take care of.<br><br>A function =
with the signature R(A..., B...) also has the signature R(A..., void, B...)=
 with typename R and typename...A, typename... B. This is to be able to bin=
d no-args functions as a function accepting a void argument, and so forth.<=
br><br>With this the example print_with_ln would certainly compile and exec=
ute.<br><br>=C2=A0-- WE<br></div></blockquote></div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_647_458626771.1438454407997--
------=_Part_646_372062841.1438454407996--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Sat, 1 Aug 2015 15:54:54 -0700
Raw View
--001a11c306ee2bfcbb051c47d3ac
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Sat, Aug 1, 2015 at 11:40 AM, Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
wrote:
>
> there's no reason to support sizeof(void), because generic code doesn't
> use that construct =E2=80=94 or if it does, it's already doing crazy thin=
gs with
> memory allocation.
>

Sorry, but I have to call you out on that as it's simply not true. Even if
you ignore the array case that was already mentioned, what about
implementing something like a variant (assuming you aren't using a union
internally, just for sake of the example)? Very commonly, you just make raw
storage that has the maximum size of all of the possible types, and an
alignment that satisfies the alignment requirements of all of the possible
types. Great, now what if one of those types happens to be void? Now all of
a sudden the code that retrieves the maximum size of all of the types would
break as soon as it internally does sizeof(void). If you need more
grounding for why this type of thing comes up in practice, consider the
following (for the record, this is based on actual code that I've worked
with very frequently in the past).

//////////
auto result =3D visit(function, some_variant);
//////////

In case it is not clear, here you are invoking function on a variant,
dispatching accordingly based on what type is in the variant. Sometimes the
return type of the invoked function differs depending on what was stored in
the variant at run time, so the overall result can be represented as a
discriminated union (another variant) of the results. If one of the return
types happened to be void, then you have to work around it again.

We shouldn't start by saying "oh, you'd never have to do that with void in
generic code, so it can differ from 'normal' types here." That is how we
got into this mess to begin with. It's a flawed rationale right from the
start. void IS just a type, like any other. Stop special casing it.


> (Also, there are 100% excellent reasons to keep sizeof(void) a SFINAE
> failure. Suddenly defining it would break a lot of existing code.)
>

I exploit SFINAE a lot and that's a real stretch. Obviously this is
necessarily a breaking change because of how easy it is to introspect C++,
but in that sense there is pretty much nothing that's not a breaking change
in the language. Give some practical, real world examples of where
sizeof(void) being an error breaks "a lot of code" in a way that shouldn't
have been written some other way to begin with.

There is no need to support "collapsing" void arguments
>

+1

There is no need to support arithmetic, relational, or logical operations
> on void operands.
>

No one is advocating arithmetic operations. We just want the type to be
Regular. Comparisons *always* make sense. Let's stop trying to make void
anything less than a regular type. Even if it's not immediately obvious to
you why you'd want to use any one of the operations expected of regular
types, you're going to simply be wrong as soon as you write any generic
code involving that operation. A simple example of generic code where you'd
want comparisons for void:

//////////
// Check that the results of function calls match
// when given different objects.
template<class T, class... Funs>
bool results_are_equal(T a, T b, Funs... funs)
{
  return    std::forward_as_tuple(funs(a)...)
         =3D=3D std::forward_as_tuple(funs(b)...);
}
//////////

If one or more of the functions happens to return void, then that's
perfectly fine. All instances of such a stateless type are equal. Just
because you know at compile time that the types are equal doesn't mean that
the operation itself is illogical.

The other comparison operators are just as sensible.


> There is no need to define the size or alignment of void objects; being
> no-ops, they wouldn't participate in class layout anyway.
>

Again, we are talking about generic code. If you make the operations an
error rather than giving a sensible result (and there are perfectly
sensible results here), then all you're doing if forcing people to work
around that in generic code.

As far as "getting things in gradually by making only some operations
valid," I don't think that is at all any easier than simply stating that
void is a complete type equivalent to:

//////////
struct void {};
constexpr bool operator =3D=3D(void, void) noexcept { return true; }
// And define the other comparisons as I did in another reply
//////////

This is very simple, and because you're not describing void as still some
special entity in the language, the rules of other types apply without
doing anything special (I.E. sizeof and alignas work fine). This also
effectively punts on the question of is sizeof(void) =3D=3D 0, since it mak=
es
no explicit mention of an exact size requirement, just like we do with most
other types in the language.

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On S=
at, Aug 1, 2015 at 11:40 AM, Arthur O&#39;Dwyer <span dir=3D"ltr">&lt;<a hr=
ef=3D"mailto:arthur.j.odwyer@gmail.com" target=3D"_blank">arthur.j.odwyer@g=
mail.com</a>&gt;</span> wrote:<blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"lt=
r"><div>there&#39;s no reason to support sizeof(void), because generic code=
 doesn&#39;t use that construct =E2=80=94 or if it does, it&#39;s already d=
oing crazy things with memory allocation.</div></div></blockquote><div><br>=
</div><div>Sorry, but I have to call you out on that as it&#39;s simply not=
 true. Even if you ignore the array case that was already mentioned, what a=
bout implementing something like a variant (assuming you aren&#39;t using a=
 union internally, just for sake of the example)? Very commonly, you just m=
ake raw storage that has the maximum size of all of the possible types, and=
 an alignment that satisfies the alignment requirements of all of the possi=
ble types. Great, now what if one of those types happens to be void? Now al=
l of a sudden the code that retrieves the maximum size of all of the types =
would break as soon as it internally does sizeof(void). If you need more gr=
ounding for why this type of thing comes up in practice, consider the follo=
wing (for the record, this is based on actual code that I&#39;ve worked wit=
h very frequently in the past).</div><div><br></div><div>//////////</div><d=
iv>auto result =3D visit(function, some_variant);<br></div><div>//////////<=
/div><div><br></div><div>In case it is not clear, here you are invoking fun=
ction on a variant, dispatching accordingly based on what type is in the va=
riant. Sometimes the return type of the invoked function differs depending =
on what was stored in the variant at run time, so the overall result can be=
 represented as a discriminated union (another variant) of the results. If =
one of the return types happened to be void, then you have to work around i=
t again.</div><div><br></div><div>We shouldn&#39;t start by saying &quot;oh=
, you&#39;d never have to do that with void in generic code, so it can diff=
er from &#39;normal&#39; types here.&quot; That is how we got into this mes=
s to begin with. It&#39;s a flawed rationale right from the start. void IS =
just a type, like any other. Stop special casing it.</div><div>=C2=A0</div>=
<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> (Also, there are 100%=
 excellent reasons to keep sizeof(void) a SFINAE failure. Suddenly defining=
 it would break a lot of existing code.)</div></div></blockquote><div><br><=
/div><div>I exploit SFINAE a lot and that&#39;s a real stretch. Obviously t=
his is necessarily a breaking change because of how easy it is to introspec=
t C++, but in that sense there is pretty much nothing that&#39;s not a brea=
king change in the language. Give some practical, real world examples of wh=
ere sizeof(void) being an error breaks &quot;a lot of code&quot; in a way t=
hat shouldn&#39;t have been written some other way to begin with.</div><div=
><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bor=
der-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>There is no=
 need to support &quot;collapsing&quot; void arguments<br></div></div></blo=
ckquote><div><br></div><div>+1</div><div><br></div><blockquote class=3D"gma=
il_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-lef=
t:1ex"><div dir=3D"ltr"><div>There is no need to support arithmetic, relati=
onal, or logical operations on void operands.</div></div></blockquote><div>=
<br></div><div>No one is advocating arithmetic operations. We just want the=
 type to be Regular. Comparisons <i>always</i> make sense. Let&#39;s stop t=
rying to make void anything less than a regular type. Even if it&#39;s not =
immediately obvious to you why you&#39;d want to use any one of the operati=
ons expected of regular types, you&#39;re going to simply be wrong as soon =
as you write any generic code involving that operation. A simple example of=
 generic code where you&#39;d want comparisons for void:</div><div><br></di=
v><div>//////////</div><div>// Check that the results of function calls mat=
ch</div><div>// when given different objects.</div><div>template&lt;class T=
, class... Funs&gt;</div><div>bool results_are_equal(T a, T b, Funs... funs=
)</div><div>{</div><div>=C2=A0 return =C2=A0 =C2=A0std::forward_as_tuple(fu=
ns(a)...)</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=3D=3D std::forward_a=
s_tuple(funs(b)...);</div><div>}</div><div>//////////</div><div><br></div><=
div>If one or more of the functions happens to return void, then that&#39;s=
 perfectly fine. All instances of such a stateless type are equal. Just bec=
ause you know at compile time that the types are equal doesn&#39;t mean tha=
t the operation itself is illogical.</div><div><br></div><div>The other com=
parison operators are just as sensible.</div><div>=C2=A0</div><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;=
padding-left:1ex"><div dir=3D"ltr"><div>There is no need to define the size=
 or alignment of void objects; being no-ops, they wouldn&#39;t participate =
in class layout anyway.</div></div></blockquote><div><br></div><div>Again, =
we are talking about generic code. If you make the operations an error rath=
er than giving a sensible result (and there are perfectly sensible results =
here), then all you&#39;re doing if forcing people to work around that in g=
eneric code.</div><div><br></div><div>As far as &quot;getting things in gra=
dually by making only some operations valid,&quot; I don&#39;t think that i=
s at all any easier than simply stating that void is a complete type equiva=
lent to:</div><div><br></div><div>//////////</div><div>struct void {};</div=
><div>constexpr bool operator =3D=3D(void, void) noexcept { return true; }<=
/div><div>// And define the other comparisons as I did in another reply</di=
v><div>//////////</div><div><br></div><div>This is very simple, and because=
 you&#39;re not describing void as still some special entity in the languag=
e, the rules of other types apply without doing anything special (I.E. size=
of and alignas work fine). This also effectively punts on the question of i=
s sizeof(void) =3D=3D 0, since it makes no explicit mention of an exact siz=
e requirement, just like we do with most other types in the language.</div>=
<div><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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a11c306ee2bfcbb051c47d3ac--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Sat, 01 Aug 2015 16:59:13 -0700
Raw View
On Saturday 01 August 2015 15:54:54 'Matt Calabrese' via ISO C++ Standard -
Future Proposals wrote:
> Sorry, but I have to call you out on that as it's simply not true. Even if
> you ignore the array case that was already mentioned, what about
> implementing something like a variant (assuming you aren't using a union
> internally, just for sake of the example)? Very commonly, you just make raw
> storage that has the maximum size of all of the possible types, and an
> alignment that satisfies the alignment requirements of all of the possible
> types. Great, now what if one of those types happens to be void? Now all of
> a sudden the code that retrieves the maximum size of all of the types would
> break as soon as it internally does sizeof(void). If you need more
> grounding for why this type of thing comes up in practice, consider the
> following (for the record, this is based on actual code that I've worked
> with very frequently in the past).

The problem isn't that a variant class couldn't be made to work with void
under those circumstances.

The problem is that people are using void in SFINAE contexts (usually, sizeof)
and expecting it to fail. Suddenly making it succeed and yield zero may break
a lot of code, quite possibly silently.

Any new use we make of void should be in contexts that it couldn't have been
used before, not even in SFINAE.

So while I'd like to do:

template <typename T> void f(T *ptr, T (*fptr)())
{
 *ptr = fptr();
}

work without specialisation for f<void> (real use-case, see Qt's
qobjectdefs_impl.h), we can probably not do:

template <typename T> void f(T value, void (*fptr)(T));

because some poor-man's enable_if may have been using expansion to a void
parameter.
--
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/.

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Sun, 2 Aug 2015 18:12:31 -0700
Raw View
--047d7b33c69e27f1c6051c5dddbf
Content-Type: text/plain; charset=UTF-8

On Sat, Aug 1, 2015 at 4:59 PM, Thiago Macieira <thiago@macieira.org> wrote:
>
> The problem is that people are using void in SFINAE contexts (usually,
> sizeof)
> and expecting it to fail. Suddenly making it succeed and yield zero may
> break
> a lot of code, quite possibly silently.


Again, I understand that this is the claim, but I doubt that it is common
or something to be horribly concerned about. Places where sizeof is used
for SFINAE exploitation generally have better alternatives. If you have
actual real code that breaks because of this and it's common, not easily
diagnosable, and not easily fixable, post it so that we are not talking in
hypotheticals. Modern SFINAE exploitation usually does not rely on sizeof.
SFINAE exploitation of expressions often uses decltype as opposed to
sizeof, since sizeof can force premature instantiation of the definition of
the operand and also because it can cause an undesirable substitution
failure with respect to void already. If code is using expansion to a void
parameter to force substitution failure, I doubt it is horribly common in
user code (is there an easy way to figure this out?). Even if it were,
sacrificing that seems very reasonable to me, given that there are more
common alternatives regarding SFINAE exploitation that have been in use for
quite a while. Making generic code easier to write correctly and removing
the need for specializations like std::promise<void> seems much more
important to the future of C++ than not breaking weird hacks that could
have/should have be done in other ways anyway.

If we are to talk about SFINAE, there are very few things you can change in
the language at all that wouldn't break some hypothetical SFINAE
exploitation because of C++'s introspection capabilities. I don't think it
makes sense to hold back progress because of that. The nature of void as an
incomplete type isn't particularly unique in this regard.

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On S=
at, Aug 1, 2015 at 4:59 PM, Thiago Macieira <span dir=3D"ltr">&lt;<a href=
=3D"mailto:thiago@macieira.org" target=3D"_blank">thiago@macieira.org</a>&g=
t;</span> wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8e=
x;border-left:1px #ccc solid;padding-left:1ex">
The problem is that people are using void in SFINAE contexts (usually, size=
of)<br>
and expecting it to fail. Suddenly making it succeed and yield zero may bre=
ak<br>
a lot of code, quite possibly silently.</blockquote><div><br></div>Again, I=
 understand that this is the claim, but I doubt that it is common or someth=
ing to be horribly concerned about. Places where sizeof is used for SFINAE =
exploitation generally have better alternatives. If you have actual real co=
de that breaks because of this and it&#39;s common, not easily diagnosable,=
 and not easily fixable, post it so that we are not talking in hypothetical=
s. Modern SFINAE exploitation usually does not rely on sizeof. SFINAE explo=
itation of expressions often uses decltype as opposed to sizeof, since size=
of can force premature instantiation of the definition of the operand and a=
lso because it can cause an undesirable substitution failure with respect t=
o void already. If code is using expansion to a void parameter to force sub=
stitution failure, I doubt it is horribly common in user code (is there an =
easy way to figure this out?). Even if it were, sacrificing that seems very=
 reasonable to me, given that there are more common alternatives regarding =
SFINAE exploitation that have been in use for quite a while. Making generic=
 code easier to write correctly and removing the need for specializations l=
ike std::promise&lt;void&gt; seems much more important to the future of C++=
 than not breaking weird hacks that could have/should have be done in other=
 ways anyway.</div><div class=3D"gmail_quote"><br></div><div class=3D"gmail=
_quote">If we are to talk about SFINAE, there are very few things you can c=
hange in the language at all that wouldn&#39;t break some hypothetical SFIN=
AE exploitation because of C++&#39;s introspection capabilities. I don&#39;=
t think it makes sense to hold back progress because of that. The nature of=
 void as an incomplete type isn&#39;t particularly unique in this regard.</=
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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--047d7b33c69e27f1c6051c5dddbf--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Sun, 02 Aug 2015 19:30:35 -0700
Raw View
On Sunday 02 August 2015 18:12:31 'Matt Calabrese' via ISO C++ Standard -
Future Proposals wrote:
> On Sat, Aug 1, 2015 at 4:59 PM, Thiago Macieira <thiago@macieira.org> wrote:
> > The problem is that people are using void in SFINAE contexts (usually,
> > sizeof)
> > and expecting it to fail. Suddenly making it succeed and yield zero may
> > break
> > a lot of code, quite possibly silently.
>
> Again, I understand that this is the claim, but I doubt that it is common
> or something to be horribly concerned about. Places where sizeof is used
> for SFINAE exploitation generally have better alternatives.

There being better alternatives does not imply the better alternatives were
used. Changing behaviour of existing code requires checking how much code
would be affected.

We're both saying that the number is non-zero. So the burden will fall on you
to prove that this non-zero number is small enough and easily fixed.

> If you have
> actual real code that breaks because of this and it's common, not easily
> diagnosable, and not easily fixable, post it so that we are not talking in
> hypotheticals. Modern SFINAE exploitation usually does not rely on sizeof.
> SFINAE exploitation of expressions often uses decltype as opposed to

decltype is a C++11 trick. Please look at the large codebase of pre-C++11
SFINAE.

> If we are to talk about SFINAE, there are very few things you can change in
> the language at all that wouldn't break some hypothetical SFINAE
> exploitation because of C++'s introspection capabilities. I don't think it
> makes sense to hold back progress because of that. The nature of void as an
> incomplete type isn't particularly unique in this regard.

There are few things that are syntactically valid but would produce an error
during template substitution. Changing those risks breaking SFINAE.

More often, when we change the language, we make code that wasn't
syntactically valid before become valid

Anyway, I'm not disagreeing with some uses of void. I'm simply agreeing with
Arthur that we should go very carefully and enable only what's really
necessary.

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

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Sun, 2 Aug 2015 20:46:27 -0700
Raw View
--089e0122e6bab003ea051c6003cf
Content-Type: text/plain; charset=UTF-8

On Sun, Aug 2, 2015 at 7:30 PM, Thiago Macieira <thiago@macieira.org> wrote:
>
> decltype is a C++11 trick. Please look at the large codebase of pre-C++11
> SFINAE.
>

Expression SFINAE wan't actually explicitly in the standard prior to C++11,
so sizeof on an expression yielding void back then was not portable to
begin with, even regarding substitution failure. If the concern with
respect to sizeof really is breakage of pre-C++11 code that was not
portable even then, then I don't see how that is a worthwhile concern. We
didn't have portable expression SFINAE until we also had decltype.

Anyway, by the time any of these changes would come in, C++11 will have
been at a minimum of 6 years old (or longer, depending on if something like
this would even be proposed by C++17). Are we really going to hold
ourselves back because of that?

As far as possible usage of void as a means to cause substitution to fail
by way of making a function have a void parameter, I find that more
compelling, and yes, that can potentially cause some code to change in
observable behavior. For that case, however, whether or not sizeof works
for void has absolutely no bearing. That case would necessarily break since
passing of void or reference-to-void is one of the more common things to
come up in generic code that we'd like to fix (It's the primary reason we
need a std::promise<void> specialization, for example, or see my tuple
example, or, in the more abstract, any generic code where you need to
invoke a function with an instance of a type that is dependent on a
template parameter where that type may or may not be void). So sizeof or no
sizeof, I think people would just have to accept that kind of change.

Getting back to whether sizeof would work or not -- if you don't allow
sizeof to work on void, I find it hard to believe that you'd be able to do
something as simple as create an array of them in the language without even
more special casing. Even if you did special-cased that, you'd probably
also need to special case pointer arithmetic on it. In short, if we only go
partway toward making void a proper type, we'll just be trading some
special casing for other special-casing further down the line, and that
special casing still needs to be specified in the standard and understood
by users of the language.

To restate, I do not advocate sizeof(void) == 0, I just advocate void being
a complete type in the manner expressed earlier, which implies that sizeof
and alignas work perfectly fine. sizeof *anything* being 0 in the language
really does break a lot of assumptions in the language and would have
implications on things as basic as arrays, etc. It would be great if we
eventually got to allowing types to truly be empty, but that is not at all
necessary to improve the state of generic programming in C++. The size of a
type being allowed to be 0 is orthogonal and I don't think it's worth
addressing in a proposal that simply makes void a regular type.

Anyway, I'm not disagreeing with some uses of void. I'm simply agreeing with
> Arthur that we should go very carefully and enable only what's really
> necessary.
>

My stance is that it's *all* really necessary if the goal truly is to not
have to needlessly special-case void when writing generic code. The claims
I'm refuting are that certain operations "don't make sense" for void. They
*do* in fact make sense, just like they make sense for other types. I am
also not at all convinced that bringing the proper changes in gradually
will make the transition any easier, whether for users or for specification
in the standard. The proper change (starting by making void a complete,
Regular type, and the other minimal changes described in earlier replies)
can be specified relatively easily, and because it doesn't rely on void
being something particularly special in the language, the rules for
"normal" types apply.

If people are genuinely concerned about breaking of some oddball SFINAE
hacks (and I say this as someone who is very liberal with usage of SFINAE
hacks), spreading out the changes only succeeds at delaying that breakage
and delays us getting a proper solution. Ultimately, these changes should
eventually be made if we want to end the special-casing of void in generic
code, and so ultimately users would have to update such code regardless of
whether the changes were made in C++17, or the next standard, or in some
future standard after that.

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On S=
un, Aug 2, 2015 at 7:30 PM, Thiago Macieira <span dir=3D"ltr">&lt;<a href=
=3D"mailto:thiago@macieira.org" target=3D"_blank">thiago@macieira.org</a>&g=
t;</span> wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8e=
x;border-left:1px #ccc solid;padding-left:1ex">decltype is a C++11 trick. P=
lease look at the large codebase of pre-C++11<br>
SFINAE.<br></blockquote><div><br></div><div>Expression SFINAE wan&#39;t act=
ually explicitly in the standard prior to C++11, so sizeof on an expression=
 yielding void back then was not portable to begin with, even regarding sub=
stitution failure. If the concern with respect to sizeof really is breakage=
 of pre-C++11 code that was not portable even then, then I don&#39;t see ho=
w that is a worthwhile concern. We didn&#39;t have portable expression SFIN=
AE until we also had decltype.</div><div><br></div><div>Anyway, by the time=
 any of these changes would come in, C++11 will have been at a minimum of 6=
 years old (or longer, depending on if something like this would even be pr=
oposed by C++17). Are we really going to hold ourselves back because of tha=
t?</div><div><br></div><div>As far as possible usage of void as a means to =
cause substitution to fail by way of making a function have a void paramete=
r, I find that more compelling, and yes, that can potentially cause some co=
de to change in observable behavior. For that case, however, whether or not=
 sizeof works for void has absolutely no bearing. That case would necessari=
ly break since passing of void or reference-to-void is one of the more comm=
on things to come up in generic code that we&#39;d like to fix (It&#39;s th=
e primary reason we need a std::promise&lt;void&gt; specialization, for exa=
mple, or see my tuple example, or, in the more abstract, any generic code w=
here you need to invoke a function with an instance of a type that is depen=
dent on a template parameter where that type may or may not be void). So si=
zeof or no sizeof, I think people would just have to accept that kind of ch=
ange.<br></div><div><br></div><div>Getting back to whether sizeof would wor=
k or not -- if you don&#39;t allow sizeof to work on void, I find it hard t=
o believe that you&#39;d be able to do something as simple as create an arr=
ay of them in the language without even more special casing. Even if you di=
d special-cased that, you&#39;d probably also need to special case pointer =
arithmetic on it. In short, if we only go partway toward making void a prop=
er type, we&#39;ll just be trading some special casing for other special-ca=
sing further down the line, and that special casing still needs to be speci=
fied in the standard and understood by users of the language.</div><div><br=
></div><div>To restate, I do not advocate sizeof(void) =3D=3D 0, I just adv=
ocate void being a complete type in the manner expressed earlier, which imp=
lies that sizeof and alignas work perfectly fine. sizeof <i>anything</i>=C2=
=A0being 0 in the language really does break a lot of assumptions in the la=
nguage and would have implications on things as basic as arrays, etc. It wo=
uld be great if we eventually got to allowing types to truly be empty, but =
that is not at all necessary to improve the state of generic programming in=
 C++. The size of a type being allowed to be 0 is orthogonal and I don&#39;=
t think it&#39;s worth addressing in a proposal that simply makes void a re=
gular type.</div><div><br></div><blockquote class=3D"gmail_quote" style=3D"=
margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Anyway, I&#3=
9;m not disagreeing with some uses of void. I&#39;m simply agreeing with<br=
>
Arthur that we should go very carefully and enable only what&#39;s really<b=
r>
necessary.<br></blockquote><div><br></div><div>My stance is that it&#39;s <=
i>all</i>=C2=A0really necessary if the goal truly is to not have to needles=
sly special-case void when writing generic code. The claims I&#39;m refutin=
g are that certain operations &quot;don&#39;t make sense&quot; for void. Th=
ey <i>do</i>=C2=A0in fact make sense, just like they make sense for other t=
ypes. I am also not at all convinced that bringing the proper changes in gr=
adually will make the transition any easier, whether for users or for speci=
fication in the standard. The proper change (starting by making void a comp=
lete, Regular type, and the other minimal changes described in earlier repl=
ies) can be specified relatively easily, and because it doesn&#39;t rely on=
 void being something particularly special in the language, the rules for &=
quot;normal&quot; types apply.</div><div><br></div><div>If people are genui=
nely concerned about breaking of some oddball SFINAE hacks (and I say this =
as someone who is very liberal with usage of SFINAE hacks), spreading out t=
he changes only succeeds at delaying that breakage and delays us getting a =
proper solution. Ultimately, these changes should eventually be made if we =
want to end the special-casing of void in generic code, and so ultimately u=
sers would have to update such code regardless of whether the changes were =
made in C++17, or the next standard, or in some future standard after that.=
</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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--089e0122e6bab003ea051c6003cf--

.


Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Sun, 2 Aug 2015 21:41:55 -0700
Raw View
--047d7bb049060c0b00051c60ca04
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Sun, Aug 2, 2015 at 8:46 PM, 'Matt Calabrese' via ISO C++ Standard -
Future Proposals <std-proposals@isocpp.org> wrote:

>
> As far as possible usage of void as a means to cause substitution to fail
> by way of making a function have a void parameter, I find that more
> compelling, and yes, that can potentially cause some code to change in
> observable behavior. For that case, however, whether or not sizeof works
> for void has absolutely no bearing. That case would necessarily break sin=
ce
> passing of void or reference-to-void is one of the more common things to
> come up in generic code that we'd like to fix (It's the primary reason we
> need a std::promise<void> specialization, for example, or see my tuple
> example, or, in the more abstract, any generic code where you need to
> invoke a function with an instance of a type that is dependent on a
> template parameter where that type may or may not be void).
>

I think it's extremely debatable whether
    std::tuple<int, void, int>
or
    std::array<void, 3>
*ought* to be permitted by the language.

I'm personally interested in getting promise<void> and future<void> to work
without special cases, but for those I don't think you need to evaluate
sizeof(void) or do pointer arithmetic on void pointers or make arrays of
void...  and you *definitely* don't need to evaluate void operands to
operator=3D=3D!  That's why I'm pushing back on this idea a bit: Let's see =
a
concrete situation where the current state of void is causing problems, and
see what the minimal fix would be for that situation.

For example, what if the following class template were proposed for
standardization?

  template<class T> struct regularize {
    T t;
    T& get() { return t; }  // assume we also provide const, rvalue, etc.
forms
    void set(T s) { t =3D s; }
  };
  template<class T> struct regularize<T&> {
    T *t;
    T& get() const { return *t; }
    void set(T& s) { t =3D &s; }
  };
  template<> struct regularize<void> {
    void get() const {}
    void set() {}
  };

Would proper use of regular<T> in place of raw T solve *all* the current
use-cases?
Well, no, it wouldn't; but at least now we can focus on a smaller number of
remaining problem cases.
I nominate

    template<class T> struct simple_future {
        regularize<T> rt;
        void set(T p) { rt.set(p); }
    };

Here we have a parameter of void type, which is currently disallowed.[*]
Once we allow that, we also have to allow the name of that parameter to
denote an expression of void type.
And then we also need to allow calling a nullary function with a single
parameter of void type.
....Or, something else needs to happen, which I merely haven't thought of
yet.

=E2=80=93Arthur

[*] ...but only if the void type is template-dependent. If the void comes
from a non-dependent typedef, it's accepted.
This might be intended to deal with the problem case of

    template<class T> void g(T) {}
    int main() {
        g();  // Should this call g<void>(void)?
        g(g(1));  // Should this?
     }

That is, even if we allow void-type arguments to functions, we might need
to specify that void *still* can't be *deduced* as a parameter type; void
arguments must appear only in non-deduced contexts.

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

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

<div dir=3D"ltr">On Sun, Aug 2, 2015 at 8:46 PM, &#39;Matt Calabrese&#39; v=
ia ISO C++ Standard - Future Proposals <span dir=3D"ltr">&lt;<a href=3D"mai=
lto:std-proposals@isocpp.org" target=3D"_blank">std-proposals@isocpp.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:=
1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra=
"><div class=3D"gmail_quote"><br></div></div></div></blockquote><blockquote=
 class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc soli=
d;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=
=3D"gmail_quote"><div>As far as possible usage of void as a means to cause =
substitution to fail by way of making a function have a void parameter, I f=
ind that more compelling, and yes, that can potentially cause some code to =
change in observable behavior. For that case, however, whether or not sizeo=
f works for void has absolutely no bearing. That case would necessarily bre=
ak since passing of void or reference-to-void is one of the more common thi=
ngs to come up in generic code that we&#39;d like to fix (It&#39;s the prim=
ary reason we need a std::promise&lt;void&gt; specialization, for example, =
or see my tuple example, or, in the more abstract, any generic code where y=
ou need to invoke a function with an instance of a type that is dependent o=
n a template parameter where that type may or may not be void).<br></div></=
div></div></div></blockquote><div><br></div><div>I think it&#39;s extremely=
 debatable whether</div><div>=C2=A0 =C2=A0 <font face=3D"monospace, monospa=
ce">std::tuple&lt;int, void, int&gt;</font></div><div>or</div><div>=C2=A0 =
=C2=A0 <font face=3D"monospace, monospace">std::array&lt;void, 3&gt;</font>=
</div><div><b><i>ought</i></b> to be permitted by the language.</div><div><=
br></div><div>I&#39;m personally interested in getting <font face=3D"monosp=
ace, monospace">promise&lt;void&gt;</font> and <font face=3D"monospace, mon=
ospace">future&lt;void&gt;</font> to work without special cases, but for th=
ose I don&#39;t think you need to evaluate <font face=3D"monospace, monospa=
ce">sizeof(void)</font>=C2=A0or do pointer arithmetic on void pointers or m=
ake arrays of <font face=3D"monospace, monospace">void</font>... =C2=A0and =
you <i>definitely</i> don&#39;t need to evaluate void operands to <font fac=
e=3D"monospace, monospace">operator=3D=3D</font>!=C2=A0 That&#39;s why I&#3=
9;m pushing back on this idea a bit: Let&#39;s see a concrete situation whe=
re the current state of <font face=3D"monospace, monospace">void</font> is =
causing problems, and see what the minimal fix would be for that situation.=
</div><div><br></div><div>For example, what if the following class template=
 were proposed for standardization?</div><div><br></div><div><font face=3D"=
monospace, monospace">=C2=A0 template&lt;class T&gt; struct regularize {</f=
ont></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 T t;</font=
></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 T&amp; get() =
{ return t; } =C2=A0// assume we also provide const, rvalue, etc. forms</fo=
nt></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 void set(T =
s) { t =3D s; }</font></div><div><font face=3D"monospace, monospace">=C2=A0=
 };<br></font></div><div><font face=3D"monospace, monospace">=C2=A0 templat=
e&lt;class T&gt; struct regularize&lt;T&amp;&gt; {<br></font></div><div><fo=
nt face=3D"monospace, monospace">=C2=A0 =C2=A0 T *t;</font></div><div><font=
 face=3D"monospace, monospace">=C2=A0 =C2=A0 T&amp; get() const { return *t=
; }</font></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 void=
 set(T&amp; s) { t =3D &amp;s; }</font></div><div><font face=3D"monospace, =
monospace">=C2=A0 };<br></font></div><div><div><font face=3D"monospace, mon=
ospace">=C2=A0 template&lt;&gt; struct regularize&lt;void&gt; {</font></div=
><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 void get() const {}=
</font></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 void se=
t() {}</font></div><div><font face=3D"monospace, monospace">=C2=A0 };</font=
><br></div></div><div><br></div><div>Would proper use of <font face=3D"mono=
space, monospace">regular&lt;T&gt;</font>=C2=A0in place of raw <font face=
=3D"monospace, monospace">T</font> solve <i>all</i> the current use-cases?<=
/div><div>Well, no, it wouldn&#39;t; but at least now we can focus on a sma=
ller number of remaining problem cases.</div><div>I nominate</div><div><br>=
</div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 template&lt;cl=
ass T&gt; struct simple_future {</font></div><div><font face=3D"monospace, =
monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 regularize&lt;T&gt; rt;</font></div>=
<div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 void s=
et(T p) { rt.set(p); }</font></div><div><font face=3D"monospace, monospace"=
>=C2=A0 =C2=A0 };</font></div><div><br></div><div>Here we have a parameter =
of void type, which is currently disallowed.[*]</div><div>Once we allow tha=
t, we also have to allow the name of that parameter to denote an expression=
 of void type.</div><div>And then we also need to allow calling a nullary f=
unction with a single parameter of void type.</div><div>...Or, something el=
se needs to happen, which I merely haven&#39;t thought of yet.</div><div><b=
r></div><div>=E2=80=93Arthur</div><div><br></div><div>[*] ...but only if th=
e void type is template-dependent. If the void comes from a non-dependent t=
ypedef, it&#39;s accepted.</div><div>This might be intended to deal with th=
e problem case of</div><div><br></div><div><font face=3D"monospace, monospa=
ce">=C2=A0 =C2=A0 template&lt;class T&gt; void g(T) {}</font></div><div><fo=
nt face=3D"monospace, monospace">=C2=A0 =C2=A0 int main() {</font></div><di=
v><font face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 g(); =C2=
=A0// Should this call g&lt;void&gt;(void)?</font></div><div><font face=3D"=
monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 g(g(1)); =C2=A0// Should =
this?</font></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 =
=C2=A0}<br></font></div><div><br></div><div>That is, even if we allow void-=
type arguments to functions, we might need to specify that void <i>still</i=
> can&#39;t be <i>deduced</i> as a parameter type; void arguments must appe=
ar only in non-deduced contexts.</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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--047d7bb049060c0b00051c60ca04--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Sun, 2 Aug 2015 23:02:44 -0700
Raw View
--001a1134fd400c6696051c61eb49
Content-Type: text/plain; charset=UTF-8

On Sun, Aug 2, 2015 at 9:41 PM, Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
wrote:

> On Sun, Aug 2, 2015 at 8:46 PM, 'Matt Calabrese' via ISO C++ Standard -
> Future Proposals <std-proposals@isocpp.org> wrote:
>
>>
>> As far as possible usage of void as a means to cause substitution to fail
>> by way of making a function have a void parameter, I find that more
>> compelling, and yes, that can potentially cause some code to change in
>> observable behavior. For that case, however, whether or not sizeof works
>> for void has absolutely no bearing. That case would necessarily break since
>> passing of void or reference-to-void is one of the more common things to
>> come up in generic code that we'd like to fix (It's the primary reason we
>> need a std::promise<void> specialization, for example, or see my tuple
>> example, or, in the more abstract, any generic code where you need to
>> invoke a function with an instance of a type that is dependent on a
>> template parameter where that type may or may not be void).
>>
>
> I think it's extremely debatable whether
>     std::tuple<int, void, int>
> or
>     std::array<void, 3>
> *ought* to be permitted by the language.
>

Why? Simply stating that they shouldn't be permitted without any rationale
isn't convincing. void can simply be thought of as a stateless type.
Treating it as something *less* than that is precisely the problem we have
today. Sean's analogy with respect to the notion of 0 is really on point.
Don't act like 0 is not a number. Just because void has no state doesn't
mean that it's not a type. It's just a type with no state. People make
empty types in C++ all of the time, and there is no reason to think of void
as anything different. Pretending that void is special is the source of why
generic code in C++ requires special casing when dealing with void. We
should be fixing the problem rather than trying to put band-aids over some
of the issues.

The way you make void easy to use in generic code is you simply *make it a
regular type with no state*. 0 is a number.

I'm personally interested in getting promise<void> and future<void> to work
> without special cases, but for those I don't think you need to evaluate
> sizeof(void) or do pointer arithmetic on void pointers or make arrays of
> void...  and you *definitely* don't need to evaluate void operands to
> operator==!
>

.... How would making operator== defined for void be a problem for you or
for anyone? Why would you draw the line there even if you didn't understand
my examples of where it comes up in generic code? I am telling you flat
out, with examples, where equality can come up in generic code (really
*all* object
types should be regular, but we can leave that for different thread...).
There is nothing special about an instantiable void that means that ==
should not work. Just because you know at compile time that two instances
of a type are equal does not mean that it is illogical to compare them.
It's perfectly fine and well defined and can come up in generic code. Why
do we define equality for array<int, 0>? Do you feel that this should be a
compile error, instead? It's just an empty type, after all. The reason it's
important is because the size of the array can be dependent and yet you
still may need to logically compare two instances. Your code shouldn't
break simply because you reached the 0 case. 0 is just a number. The same
is true for void -- the result of a function may be a dependent type
(including void) but you still may logically compare the result in your
generic code. It's just a type without state. 0 is just a number.

For example, what if the following class template were proposed for
> standardization?
>
>   template<class T> struct regularize {
>     T t;
>     T& get() { return t; }  // assume we also provide const, rvalue, etc.
> forms
>     void set(T s) { t = s; }
>   };
>   template<class T> struct regularize<T&> {
>     T *t;
>     T& get() const { return *t; }
>     void set(T& s) { t = &s; }
>   };
>   template<> struct regularize<void> {
>     void get() const {}
>     void set() {}
>   };
>
> Would proper use of regular<T> in place of raw T solve *all* the current
> use-cases?
>

No. I already gave a simple example of what that wouldn't cover -- a
function that returns a tuple of results of function calls. I'm sorry that
you do not accept that specifically as important, but it can and has come
up in generic code, including actual code that I have written and that is
used. If you haven't encountered situations such as these then you're just
not writing generic code that deals with void when it is dependent and used
with composition of other algorithms. Creating helper templates that try to
push some of the special casing off does not accomplish the goal of
actually removing the need for hacks and special casing, it just tries to
standardize even more hacks. If we actually fix the language, we don't need
these workarounds at all. 0 is just a number.


> Well, no, it wouldn't; but at least now we can focus on a smaller number
> of remaining problem cases.
> I nominate
>
>     template<class T> struct simple_future {
>         regularize<T> rt;
>         void set(T p) { rt.set(p); }
>     };
>

Don't you see what you are doing? You're just introducing more and more
facilities to handle special casing rather than simply removing the need
for the special casing. You are advocating that whenever people write
generic code where void may come up, they need to go through a level of
indirection though some standard template with specializations and
overloads. Stop. This is the kind of stuff that we are already doing. We
want to stop the need for specializations and extra indirection, and
knowledge of tricks in order to write very simple generic code. We don't
want to standardize more hacks. Fix the language. 0 is a number. void is a
stateless type.

....Or, something else needs to happen, which I merely haven't thought of
> yet.
>

.... Or you could make void a regular type (the definition of which is
already smaller than your incomplete attempts at workarounds). This
*actually* covers the cases, including the ones that we didn't enumerate in
this thread, without adding any templates to the standard library that do
not solve the underlying problem while still leaving generic code that
deals with void as needlessly complicated to write. If we just make void
regular, users can write generic code that [potentially] deals with void
exactly as they'd write it now if they weren't covering the void "corner
case." Stop treating void as something special. It's not.

And 0 is a number.

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On S=
un, Aug 2, 2015 at 9:41 PM, Arthur O&#39;Dwyer <span dir=3D"ltr">&lt;<a hre=
f=3D"mailto:arthur.j.odwyer@gmail.com" target=3D"_blank">arthur.j.odwyer@gm=
ail.com</a>&gt;</span> wrote:<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"><span>On Sun, Aug 2, 2015 at 8:46 PM, &#39;Matt Calabrese&#39; via IS=
O C++ Standard - Future Proposals <span dir=3D"ltr">&lt;<a href=3D"mailto:s=
td-proposals@isocpp.org" target=3D"_blank">std-proposals@isocpp.org</a>&gt;=
</span> wrote:<br></span><div class=3D"gmail_extra"><div class=3D"gmail_quo=
te"><span><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bord=
er-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gma=
il_extra"><div class=3D"gmail_quote"><br></div></div></div></blockquote><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"><div class=3D"gmail_extra"><di=
v class=3D"gmail_quote"><div>As far as possible usage of void as a means to=
 cause substitution to fail by way of making a function have a void paramet=
er, I find that more compelling, and yes, that can potentially cause some c=
ode to change in observable behavior. For that case, however, whether or no=
t sizeof works for void has absolutely no bearing. That case would necessar=
ily break since passing of void or reference-to-void is one of the more com=
mon things to come up in generic code that we&#39;d like to fix (It&#39;s t=
he primary reason we need a std::promise&lt;void&gt; specialization, for ex=
ample, or see my tuple example, or, in the more abstract, any generic code =
where you need to invoke a function with an instance of a type that is depe=
ndent on a template parameter where that type may or may not be void).<br><=
/div></div></div></div></blockquote><div><br></div></span><div>I think it&#=
39;s extremely debatable whether</div><div>=C2=A0 =C2=A0 <font face=3D"mono=
space, monospace">std::tuple&lt;int, void, int&gt;</font></div><div>or</div=
><div>=C2=A0 =C2=A0 <font face=3D"monospace, monospace">std::array&lt;void,=
 3&gt;</font></div><div><b><i>ought</i></b> to be permitted by the language=
..</div></div></div></div></blockquote><div><br></div><div>Why? Simply stati=
ng that they shouldn&#39;t be permitted without any rationale isn&#39;t con=
vincing. void can simply be thought of as a stateless type. Treating it as =
something <i>less</i>=C2=A0than that is precisely the problem we have today=
.. Sean&#39;s analogy with respect to the notion of 0 is really on point. Do=
n&#39;t act like 0 is not a number. Just because void has no state doesn&#3=
9;t mean that it&#39;s not a type. It&#39;s just a type with no state. Peop=
le make empty types in C++ all of the time, and there is no reason to think=
 of void as anything different. Pretending that void is special is the sour=
ce of why generic code in C++ requires special casing when dealing with voi=
d. We should be fixing the problem rather than trying to put band-aids over=
 some of the issues.</div><div><br></div><div>The way you make void easy to=
 use in generic code is you simply <i>make it a regular type with no state<=
/i>. 0 is a number.</div><div><br></div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div=
 dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div></d=
iv><div>I&#39;m personally interested in getting <font face=3D"monospace, m=
onospace">promise&lt;void&gt;</font> and <font face=3D"monospace, monospace=
">future&lt;void&gt;</font> to work without special cases, but for those I =
don&#39;t think you need to evaluate <font face=3D"monospace, monospace">si=
zeof(void)</font>=C2=A0or do pointer arithmetic on void pointers or make ar=
rays of <font face=3D"monospace, monospace">void</font>... =C2=A0and you <i=
>definitely</i> don&#39;t need to evaluate void operands to <font face=3D"m=
onospace, monospace">operator=3D=3D</font>!</div></div></div></div></blockq=
uote><div>=C2=A0</div><div>... How would making operator=3D=3D defined for =
void be a problem for you or for anyone? Why would you draw the line there =
even if you didn&#39;t understand my examples of where it comes up in gener=
ic code? I am telling you flat out, with examples, where equality can come =
up in generic code (really <i>all</i>=C2=A0object types should be regular, =
but we can leave that for different thread...). There is nothing special ab=
out an instantiable void that means that =3D=3D should not work. Just becau=
se you know at compile time that two instances of a type are equal does not=
 mean that it is illogical to compare them. It&#39;s perfectly fine and wel=
l defined and can come up in generic code. Why do we define equality for ar=
ray&lt;int, 0&gt;? Do you feel that this should be a compile error, instead=
? It&#39;s just an empty type, after all. The reason it&#39;s important is =
because the size of the array can be dependent and yet you still may need t=
o logically compare two instances. Your code shouldn&#39;t break simply bec=
ause you reached the 0 case. 0 is just a number. The same is true for void =
-- the result of a function may be a dependent type (including void) but yo=
u still may logically compare the result in your generic code. It&#39;s jus=
t a type without state. 0 is just a number.</div><div><br></div><blockquote=
 class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc soli=
d;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=
=3D"gmail_quote"><div>For example, what if the following class template wer=
e proposed for standardization?<br></div><div><br></div><div><font face=3D"=
monospace, monospace">=C2=A0 template&lt;class T&gt; struct regularize {</f=
ont></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 T t;</font=
></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 T&amp; get() =
{ return t; } =C2=A0// assume we also provide const, rvalue, etc. forms</fo=
nt></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 void set(T =
s) { t =3D s; }</font></div><div><font face=3D"monospace, monospace">=C2=A0=
 };<br></font></div><div><font face=3D"monospace, monospace">=C2=A0 templat=
e&lt;class T&gt; struct regularize&lt;T&amp;&gt; {<br></font></div><div><fo=
nt face=3D"monospace, monospace">=C2=A0 =C2=A0 T *t;</font></div><div><font=
 face=3D"monospace, monospace">=C2=A0 =C2=A0 T&amp; get() const { return *t=
; }</font></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 void=
 set(T&amp; s) { t =3D &amp;s; }</font></div><div><font face=3D"monospace, =
monospace">=C2=A0 };<br></font></div><div><div><font face=3D"monospace, mon=
ospace">=C2=A0 template&lt;&gt; struct regularize&lt;void&gt; {</font></div=
><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 void get() const {}=
</font></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 void se=
t() {}</font></div><div><font face=3D"monospace, monospace">=C2=A0 };</font=
><br></div></div><div><br></div><div>Would proper use of <font face=3D"mono=
space, monospace">regular&lt;T&gt;</font>=C2=A0in place of raw <font face=
=3D"monospace, monospace">T</font> solve <i>all</i> the current use-cases?<=
/div></div></div></div></blockquote><div><br></div><div>No. I already gave =
a simple example of what that wouldn&#39;t cover -- a function that returns=
 a tuple of results of function calls. I&#39;m sorry that you do not accept=
 that specifically as important, but it can and has come up in generic code=
, including actual code that I have written and that is used. If you haven&=
#39;t encountered situations such as these then you&#39;re just not writing=
 generic code that deals with void when it is dependent and used with compo=
sition of other algorithms. Creating helper templates that try to push some=
 of the special casing off does not accomplish the goal of actually removin=
g the need for hacks and special casing, it just tries to standardize even =
more hacks. If we actually fix the language, we don&#39;t need these workar=
ounds at all. 0 is just a number.</div><div>=C2=A0</div><blockquote class=
=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gma=
il_quote"><div>Well, no, it wouldn&#39;t; but at least now we can focus on =
a smaller number of remaining problem cases.</div><div>I nominate</div><div=
><br></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 template&=
lt;class T&gt; struct simple_future {</font></div><div><font face=3D"monosp=
ace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 regularize&lt;T&gt; rt;</font><=
/div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 v=
oid set(T p) { rt.set(p); }</font></div><div><font face=3D"monospace, monos=
pace">=C2=A0 =C2=A0 };</font></div></div></div></div></blockquote><div><br>=
</div><div>Don&#39;t you see what you are doing? You&#39;re just introducin=
g more and more facilities to handle special casing rather than simply remo=
ving the need for the special casing. You are advocating that whenever peop=
le write generic code where void may come up, they need to go through a lev=
el of indirection though some standard template with specializations and ov=
erloads. Stop. This is the kind of stuff that we are already doing. We want=
 to stop the need for specializations and extra indirection, and knowledge =
of tricks in order to write very simple generic code. We don&#39;t want to =
standardize more hacks. Fix the language. 0 is a number. void is a stateles=
s type.</div><div><br></div><blockquote class=3D"gmail_quote" style=3D"marg=
in:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"=
><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div>...Or, somethin=
g else needs to happen, which I merely haven&#39;t thought of yet.</div></d=
iv></div></div></blockquote><div><br></div><div>... Or you could make void =
a regular type (the definition of which is already smaller than your incomp=
lete attempts at workarounds). This <i>actually</i> covers the cases, inclu=
ding the ones that we didn&#39;t enumerate in this thread, without adding a=
ny templates to the standard library that do not solve the underlying probl=
em while still leaving generic code that deals with void as needlessly comp=
licated to write. If we just make void regular, users can write generic cod=
e that [potentially] deals with void exactly as they&#39;d write it now if =
they weren&#39;t covering the void &quot;corner case.&quot; Stop treating v=
oid as something special. It&#39;s not.</div><div><br></div><div>And 0 is a=
 number.</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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a1134fd400c6696051c61eb49--

.


Author: David Krauss <potswa@gmail.com>
Date: Mon, 3 Aug 2015 14:09:45 +0800
Raw View
--Apple-Mail=_654CA678-2C66-4483-A495-A38646D550EE
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8


> On 2015=E2=80=9308=E2=80=9303, at 12:41 PM, Arthur O'Dwyer <arthur.j.odwy=
er@gmail.com> wrote:
>=20
> I think it's extremely debatable whether
>     std::tuple<int, void, int>
> or
>     std::array<void, 3>
> ought to be permitted by the language.

I=E2=80=99m not following very closely, but note that std::tuple does have =
std::ignore which acts as a bit-bucket.

Perhaps it could be sufficient to map void to a bit-bucket type, as an alte=
rnative approach to regularize. Either way, you still have to deal with fun=
ctions taking zero vs. one parameter.

>     template<class T> struct simple_future {
>         regularize<T> rt;
>         void set(T p) { rt.set(p); }
>     };


void set( std::tuple_element< std::tuple< T >, unpack_sequence( ! std::is_v=
oid_v< T > ) > const & ... p )
    { rt.set( p ... ); }

The pack p is length zero or one, depending on the Boolean result of is_voi=
d. The unpack_sequence operator is from a recent thread here; it creates an=
 unexpanded pack of std::size_t values. It=E2=80=99s OK to mention type typ=
ename std::tuple< void > as long as it doesn=E2=80=99t get instantiated.

Ugly? Yes. Too clever? Maybe. Just mentioning it.

--=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=_654CA678-2C66-4483-A495-A38646D550EE
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=80=9308=
=E2=80=9303, at 12:41 PM, Arthur O'Dwyer &lt;<a href=3D"mailto:arthur.j.odw=
yer@gmail.com" class=3D"">arthur.j.odwyer@gmail.com</a>&gt; wrote:</div><br=
 class=3D"Apple-interchange-newline"><div class=3D""><div style=3D"font-fam=
ily: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; =
font-weight: normal; letter-spacing: normal; line-height: normal; orphans: =
auto; text-align: start; text-indent: 0px; text-transform: none; white-spac=
e: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;=
" class=3D"">I think it's extremely debatable whether</div><div style=3D"fo=
nt-family: Helvetica; font-size: 12px; font-style: normal; font-variant: no=
rmal; font-weight: normal; letter-spacing: normal; line-height: normal; orp=
hans: auto; text-align: start; text-indent: 0px; text-transform: none; whit=
e-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width=
: 0px;" class=3D"">&nbsp; &nbsp;<span class=3D"Apple-converted-space">&nbsp=
;</span><font face=3D"monospace, monospace" class=3D"">std::tuple&lt;int, v=
oid, int&gt;</font></div><div style=3D"font-family: Helvetica; font-size: 1=
2px; font-style: normal; font-variant: normal; font-weight: normal; letter-=
spacing: normal; line-height: normal; orphans: auto; text-align: start; tex=
t-indent: 0px; text-transform: none; white-space: normal; widows: auto; wor=
d-spacing: 0px; -webkit-text-stroke-width: 0px;" class=3D"">or</div><div st=
yle=3D"font-family: Helvetica; font-size: 12px; font-style: normal; font-va=
riant: normal; font-weight: normal; letter-spacing: normal; line-height: no=
rmal; orphans: auto; text-align: start; text-indent: 0px; text-transform: n=
one; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-str=
oke-width: 0px;" class=3D"">&nbsp; &nbsp;<span class=3D"Apple-converted-spa=
ce">&nbsp;</span><font face=3D"monospace, monospace" class=3D"">std::array&=
lt;void, 3&gt;</font></div><div style=3D"font-family: Helvetica; font-size:=
 12px; font-style: normal; font-variant: normal; font-weight: normal; lette=
r-spacing: normal; line-height: normal; orphans: auto; text-align: start; t=
ext-indent: 0px; text-transform: none; white-space: normal; widows: auto; w=
ord-spacing: 0px; -webkit-text-stroke-width: 0px;" class=3D""><b class=3D""=
><i class=3D"">ought</i></b><span class=3D"Apple-converted-space">&nbsp;</s=
pan>to be permitted by the language.</div></div></blockquote></div><br clas=
s=3D""><div class=3D"">I=E2=80=99m not following very closely, but note tha=
t <font face=3D"Courier" class=3D"">std::tuple</font> does have <font face=
=3D"Courier" class=3D"">std::ignore</font> which acts as a bit-bucket.</div=
><div class=3D""><br class=3D""></div><div class=3D"">Perhaps it could be s=
ufficient to map <font face=3D"Courier" class=3D"">void</font> to a bit-buc=
ket type, as an alternative approach to <font face=3D"Courier" class=3D"">r=
egularize</font>. Either way, you still have to deal with functions taking =
zero vs. one parameter.</div><div class=3D""><br class=3D""></div><div clas=
s=3D""><blockquote type=3D"cite" class=3D""><div class=3D""><font face=3D"m=
onospace, monospace" class=3D"">&nbsp; &nbsp; template&lt;class T&gt; struc=
t simple_future {</font></div><div class=3D""><font face=3D"monospace, mono=
space" class=3D"">&nbsp; &nbsp; &nbsp; &nbsp; regularize&lt;T&gt; rt;</font=
></div><div class=3D""><font face=3D"monospace, monospace" class=3D"">&nbsp=
; &nbsp; &nbsp; &nbsp; void set(T p) { rt.set(p); }</font></div><div class=
=3D""><font face=3D"monospace, monospace" class=3D"">&nbsp; &nbsp; };</font=
></div></blockquote></div><div class=3D""><div class=3D""><font face=3D"mon=
ospace, monospace" class=3D""><br class=3D""></font></div></div><div class=
=3D""><font face=3D"monospace, monospace" class=3D"">void set( std::tuple_e=
lement&lt; std::tuple&lt; T &gt;, unpack_sequence( ! std::is_void_v&lt; T &=
gt; ) &gt; const &amp; ... p )</font></div><div class=3D""><font face=3D"mo=
nospace, monospace" class=3D"">&nbsp; &nbsp; { rt.set( p ... ); }</font></d=
iv><div class=3D""><br class=3D""></div><div class=3D"">The pack <font face=
=3D"Courier" class=3D"">p</font> is length zero or one, depending on the Bo=
olean result of <font face=3D"Courier" class=3D"">is_void</font>. The&nbsp;=
<span style=3D"font-family: monospace, monospace;" class=3D"">unpack_sequen=
ce</span>&nbsp;operator is from a recent thread here; it creates an unexpan=
ded pack of <font face=3D"Courier" class=3D"">std::size_t</font> values. It=
=E2=80=99s OK to mention type typename <font face=3D"Courier" class=3D"">st=
d::tuple&lt; void &gt;</font> as long as it doesn=E2=80=99t get instantiate=
d.</div><div class=3D""><br class=3D""></div><div class=3D"">Ugly? Yes. Too=
 clever? Maybe. Just mentioning it.</div><div class=3D""><br class=3D""></d=
iv></body></html>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_654CA678-2C66-4483-A495-A38646D550EE--

.


Author: Paul Fultz II <pfultz28@gmail.com>
Date: Mon, 3 Aug 2015 02:58:38 -0700 (PDT)
Raw View
------=_Part_671_922967981.1438595918503
Content-Type: multipart/alternative;
 boundary="----=_Part_672_1409988588.1438595918508"

------=_Part_672_1409988588.1438595918508
Content-Type: text/plain; charset=UTF-8



On Monday, August 3, 2015 at 1:02:46 AM UTC-5, Matt Calabrese wrote:
>
> On Sun, Aug 2, 2015 at 9:41 PM, Arthur O'Dwyer <arthur....@gmail.com
> <javascript:>> wrote:
>
>> On Sun, Aug 2, 2015 at 8:46 PM, 'Matt Calabrese' via ISO C++ Standard -
>> Future Proposals <std-pr...@isocpp.org <javascript:>> wrote:
>>
>>>
>>> As far as possible usage of void as a means to cause substitution to
>>> fail by way of making a function have a void parameter, I find that more
>>> compelling, and yes, that can potentially cause some code to change in
>>> observable behavior. For that case, however, whether or not sizeof works
>>> for void has absolutely no bearing. That case would necessarily break since
>>> passing of void or reference-to-void is one of the more common things to
>>> come up in generic code that we'd like to fix (It's the primary reason we
>>> need a std::promise<void> specialization, for example, or see my tuple
>>> example, or, in the more abstract, any generic code where you need to
>>> invoke a function with an instance of a type that is dependent on a
>>> template parameter where that type may or may not be void).
>>>
>>
>> I think it's extremely debatable whether
>>     std::tuple<int, void, int>
>> or
>>     std::array<void, 3>
>> *ought* to be permitted by the language.
>>
>
They should be permitted and they should be equivalent of `void`.


>
> Why? Simply stating that they shouldn't be permitted without any rationale
> isn't convincing. void can simply be thought of as a stateless type.
> Treating it as something *less* than that is precisely the problem we
> have today. Sean's analogy with respect to the notion of 0 is really on
> point. Don't act like 0 is not a number. Just because void has no state
> doesn't mean that it's not a type. It's just a type with no state. People
> make empty types in C++ all of the time, and there is no reason to think of
> void as anything different. Pretending that void is special is the source
> of why generic code in C++ requires special casing when dealing with void.
> We should be fixing the problem rather than trying to put band-aids over
> some of the issues.
>

Ok, an empty type or a stateless type is a type that has a state of at
least one, because the very existence of the type creates state. This is
why creating a struct of two empty types has the same state as an empty
type(ie `1 * 1 = 1`) or creating a variant of two empty types has the same
state as a boolean(ie `1 + 1 = 2`). However, `void` is different, and so
should be treated as a type with zero state. As such, using `void` as a
member to a struct(or `tuple<int, void>`) should be equivalent to `void`
because `x * 0 = 0`.

--

---
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_672_1409988588.1438595918508
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<br><br>On Monday, August 3, 2015 at 1:02:46 AM UTC-5, Matt Calabrese wrote=
:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bo=
rder-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div cl=
ass=3D"gmail_quote">On Sun, Aug 2, 2015 at 9:41 PM, Arthur O&#39;Dwyer <spa=
n dir=3D"ltr">&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-=
mailto=3D"d-afWwF8DwAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;ja=
vascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;r=
eturn true;">arthur....@gmail.com</a>&gt;</span> wrote:<br><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;pad=
ding-left:1ex"><div dir=3D"ltr"><span>On Sun, Aug 2, 2015 at 8:46 PM, &#39;=
Matt Calabrese&#39; via ISO C++ Standard - Future Proposals <span dir=3D"lt=
r">&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"d=
-afWwF8DwAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:&#=
39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true;=
">std-pr...@isocpp.org</a>&gt;</span> wrote:<br></span><div><div class=3D"g=
mail_quote"><span><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><div=
 class=3D"gmail_quote"><br></div></div></div></blockquote><blockquote class=
=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div>As far =
as possible usage of void as a means to cause substitution to fail by way o=
f making a function have a void parameter, I find that more compelling, and=
 yes, that can potentially cause some code to change in observable behavior=
.. For that case, however, whether or not sizeof works for void has absolute=
ly no bearing. That case would necessarily break since passing of void or r=
eference-to-void is one of the more common things to come up in generic cod=
e that we&#39;d like to fix (It&#39;s the primary reason we need a std::pro=
mise&lt;void&gt; specialization, for example, or see my tuple example, or, =
in the more abstract, any generic code where you need to invoke a function =
with an instance of a type that is dependent on a template parameter where =
that type may or may not be void).<br></div></div></div></div></blockquote>=
<div><br></div></span><div>I think it&#39;s extremely debatable whether</di=
v><div>=C2=A0 =C2=A0 <font face=3D"monospace, monospace">std::tuple&lt;int,=
 void, int&gt;</font></div><div>or</div><div>=C2=A0 =C2=A0 <font face=3D"mo=
nospace, monospace">std::array&lt;void, 3&gt;</font></div><div><b><i>ought<=
/i></b> to be permitted by the language.</div></div></div></div></blockquot=
e></div></div></div></blockquote><div><br>They should be permitted and they=
 should be equivalent of `void`.<br>=C2=A0</div><blockquote class=3D"gmail_=
quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;pa=
dding-left: 1ex;"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div><br=
></div><div>Why? Simply stating that they shouldn&#39;t be permitted withou=
t any rationale isn&#39;t convincing. void can simply be thought of as a st=
ateless type. Treating it as something <i>less</i>=C2=A0than that is precis=
ely the problem we have today. Sean&#39;s analogy with respect to the notio=
n of 0 is really on point. Don&#39;t act like 0 is not a number. Just becau=
se void has no state doesn&#39;t mean that it&#39;s not a type. It&#39;s ju=
st a type with no state. People make empty types in C++ all of the time, an=
d there is no reason to think of void as anything different. Pretending tha=
t void is special is the source of why generic code in C++ requires special=
 casing when dealing with void. We should be fixing the problem rather than=
 trying to put band-aids over some of the issues.</div></div></div></div></=
blockquote><div><br>Ok, an empty type or a stateless type is a type that ha=
s a state of at least one, because the very existence of the type creates s=
tate. This is why creating a struct of two empty types has the same state a=
s an empty type(ie `1 * 1 =3D 1`) or creating a variant of two empty types =
has the same state as a boolean(ie `1 + 1 =3D 2`). However, `void` is diffe=
rent, and so should be treated as a type with zero state. As such, using `v=
oid` as a member to a struct(or `tuple&lt;int, void&gt;`) should be equival=
ent to `void` because `x * 0 =3D 0`. <br><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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_672_1409988588.1438595918508--
------=_Part_671_922967981.1438595918503--

.


Author: Magnus Fromreide <magfr@lysator.liu.se>
Date: Mon, 3 Aug 2015 13:35:50 +0200
Raw View
On Mon, Aug 03, 2015 at 02:58:38AM -0700, Paul Fultz II wrote:
>
>
> On Monday, August 3, 2015 at 1:02:46 AM UTC-5, Matt Calabrese wrote:
> >
> > On Sun, Aug 2, 2015 at 9:41 PM, Arthur O'Dwyer <arthur....@gmail.com
> > <javascript:>> wrote:
> >
> >> On Sun, Aug 2, 2015 at 8:46 PM, 'Matt Calabrese' via ISO C++ Standard -
> >> Future Proposals <std-pr...@isocpp.org <javascript:>> wrote:
> >>
> >>>
> >>> As far as possible usage of void as a means to cause substitution to
> >>> fail by way of making a function have a void parameter, I find that more
> >>> compelling, and yes, that can potentially cause some code to change in
> >>> observable behavior. For that case, however, whether or not sizeof works
> >>> for void has absolutely no bearing. That case would necessarily break since
> >>> passing of void or reference-to-void is one of the more common things to
> >>> come up in generic code that we'd like to fix (It's the primary reason we
> >>> need a std::promise<void> specialization, for example, or see my tuple
> >>> example, or, in the more abstract, any generic code where you need to
> >>> invoke a function with an instance of a type that is dependent on a
> >>> template parameter where that type may or may not be void).
> >>>
> >>
> >> I think it's extremely debatable whether
> >>     std::tuple<int, void, int>
> >> or
> >>     std::array<void, 3>
> >> *ought* to be permitted by the language.
> >>
> >
> They should be permitted and they should be equivalent of `void`.
>
>
> >
> > Why? Simply stating that they shouldn't be permitted without any rationale
> > isn't convincing. void can simply be thought of as a stateless type.
> > Treating it as something *less* than that is precisely the problem we
> > have today. Sean's analogy with respect to the notion of 0 is really on
> > point. Don't act like 0 is not a number. Just because void has no state
> > doesn't mean that it's not a type. It's just a type with no state. People
> > make empty types in C++ all of the time, and there is no reason to think of
> > void as anything different. Pretending that void is special is the source
> > of why generic code in C++ requires special casing when dealing with void.
> > We should be fixing the problem rather than trying to put band-aids over
> > some of the issues.
> >
>
> Ok, an empty type or a stateless type is a type that has a state of at
> least one, because the very existence of the type creates state. This is
> why creating a struct of two empty types has the same state as an empty
> type(ie `1 * 1 = 1`) or creating a variant of two empty types has the same
> state as a boolean(ie `1 + 1 = 2`). However, `void` is different, and so
> should be treated as a type with zero state. As such, using `void` as a
> member to a struct(or `tuple<int, void>`) should be equivalent to `void`
> because `x * 0 = 0`.

How should incomplete types other than void, like for example

struct incomplete;

be handled under your proposal, should they get the same new features that you
are proposing for void, or should void be an odd exception?

/MF

--

---
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: Paul Fultz II <pfultz28@gmail.com>
Date: Mon, 3 Aug 2015 07:39:33 -0700 (PDT)
Raw View
------=_Part_778_1510729743.1438612773909
Content-Type: multipart/alternative;
 boundary="----=_Part_779_1618612009.1438612773910"

------=_Part_779_1618612009.1438612773910
Content-Type: text/plain; charset=UTF-8



>
> How should incomplete types other than void, like for example
>
> struct incomplete;
>
> be handled under your proposal, should they get the same new features that
> you
> are proposing for void, or should void be an odd exception?
>

Probably not. A union with an incomplete type member should be an
incomplete type, because it is an yet-to-be-determined size, whereas if the
union has a void member it should essentially be ignored.



>
> /MF
>

--

---
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_779_1618612009.1438612773910
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<br>How should incomplete types other than void, like for example
<br>
<br>struct incomplete;
<br>
<br>be handled under your proposal, should they get the same new features t=
hat you
<br>are proposing for void, or should void be an odd exception?
<br></blockquote><div><br>Probably not. A union with an incomplete type mem=
ber should be an incomplete type, because it is an yet-to-be-determined siz=
e, whereas if the union has a void member it should essentially be ignored.=
<br><br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<br>/MF
<br></blockquote></div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_779_1618612009.1438612773910--
------=_Part_778_1510729743.1438612773909--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Mon, 3 Aug 2015 10:40:02 -0700
Raw View
--047d7bd7648ece4cba051c6ba822
Content-Type: text/plain; charset=UTF-8

On Mon, Aug 3, 2015 at 2:58 AM, Paul Fultz II <pfultz28@gmail.com> wrote:

>
>
> On Monday, August 3, 2015 at 1:02:46 AM UTC-5, Matt Calabrese wrote:
>>
>> On Sun, Aug 2, 2015 at 9:41 PM, Arthur O'Dwyer <arthur....@gmail.com>
>> wrote:
>>
>>> On Sun, Aug 2, 2015 at 8:46 PM, 'Matt Calabrese' via ISO C++ Standard -
>>> Future Proposals <std-pr...@isocpp.org> wrote:
>>>
>>>>
>>>> As far as possible usage of void as a means to cause substitution to
>>>> fail by way of making a function have a void parameter, I find that more
>>>> compelling, and yes, that can potentially cause some code to change in
>>>> observable behavior. For that case, however, whether or not sizeof works
>>>> for void has absolutely no bearing. That case would necessarily break since
>>>> passing of void or reference-to-void is one of the more common things to
>>>> come up in generic code that we'd like to fix (It's the primary reason we
>>>> need a std::promise<void> specialization, for example, or see my tuple
>>>> example, or, in the more abstract, any generic code where you need to
>>>> invoke a function with an instance of a type that is dependent on a
>>>> template parameter where that type may or may not be void).
>>>>
>>>
>>> I think it's extremely debatable whether
>>>     std::tuple<int, void, int>
>>> or
>>>     std::array<void, 3>
>>> *ought* to be permitted by the language.
>>>
>>
> They should be permitted and they should be equivalent of `void`.
>

Well, not exactly. They should definitely be permitted, but std::tuple<int,
void, int> especially is not equivalent to void (the array one can be
"equivalent" depending on our equivalence function, but I guess that's true
for anything, though it certainly differs on type!). A set that contains
one or more null sets is not, itself, a null set. I'm not approximating
when I say that void should just be like a user-defined type that has no
members and is regular. That really is all that it should be. You should
expect tuple<int, void, int> to behave just like if you had tuple<int,
some_user_defined_empty_type, int>. That's all it is, and that is what you
expect it to be when you are writing generic code. You shouldn't try to
reintroduce special casing. It's just a type that doesn't have members.

Ok, an empty type or a stateless type is a type that has a state of at
> least one, because the very existence of the type creates state. This is
> why creating a struct of two empty types has the same state as an empty
> type(ie `1 * 1 = 1`) or creating a variant of two empty types has the same
> state as a boolean(ie `1 + 1 = 2`). However, `void` is different, and so
> should be treated as a type with zero state. As such, using `void` as a
> member to a struct(or `tuple<int, void>`) should be equivalent to `void`
> because `x * 0 = 0`.
>

What? No. void is not special here. It's just like any user-defined type
without members except it happens to be a built-in type. If you put an
instance of your own empty type in a struct, that struct doesn't become
empty. If you don't see why this hurts things in practice, again, just
consider something as simple as a function that returns the result of N
function calls as a tuple of size N. There is nothing logically wrong with
this even if one of the functions doesn't have to return a type that
contains state. You should be able to access any of results, iterate over
the results, etc. Algorithms on regular types should simply work on it
because there is absolutely no reason, other than manufactured reasons, for
why they wouldn't. void is not special here. It's just an empty type.
Representing it as something less than or different than object types only
hurts things.

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On M=
on, Aug 3, 2015 at 2:58 AM, Paul Fultz II <span dir=3D"ltr">&lt;<a href=3D"=
mailto:pfultz28@gmail.com" target=3D"_blank">pfultz28@gmail.com</a>&gt;</sp=
an> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;=
border-left:1px #ccc solid;padding-left:1ex"><br><br>On Monday, August 3, 2=
015 at 1:02:46 AM UTC-5, Matt Calabrese wrote:<blockquote class=3D"gmail_qu=
ote" 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">On Sun, Aug 2, =
2015 at 9:41 PM, Arthur O&#39;Dwyer <span dir=3D"ltr">&lt;<a rel=3D"nofollo=
w">arthur....@gmail.com</a>&gt;</span> wrote:<span class=3D""><br><blockquo=
te class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc so=
lid;padding-left:1ex"><div dir=3D"ltr"><span>On Sun, Aug 2, 2015 at 8:46 PM=
, &#39;Matt Calabrese&#39; via ISO C++ Standard - Future Proposals <span di=
r=3D"ltr">&lt;<a rel=3D"nofollow">std-pr...@isocpp.org</a>&gt;</span> wrote=
:<br></span><div><div class=3D"gmail_quote"><span><blockquote class=3D"gmai=
l_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left=
:1ex"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><br></div></div></di=
v></blockquote><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><div cl=
ass=3D"gmail_quote"><div>As far as possible usage of void as a means to cau=
se substitution to fail by way of making a function have a void parameter, =
I find that more compelling, and yes, that can potentially cause some code =
to change in observable behavior. For that case, however, whether or not si=
zeof works for void has absolutely no bearing. That case would necessarily =
break since passing of void or reference-to-void is one of the more common =
things to come up in generic code that we&#39;d like to fix (It&#39;s the p=
rimary reason we need a std::promise&lt;void&gt; specialization, for exampl=
e, or see my tuple example, or, in the more abstract, any generic code wher=
e you need to invoke a function with an instance of a type that is dependen=
t on a template parameter where that type may or may not be void).<br></div=
></div></div></div></blockquote><div><br></div></span><div>I think it&#39;s=
 extremely debatable whether</div><div>=C2=A0 =C2=A0 <font face=3D"monospac=
e, monospace">std::tuple&lt;int, void, int&gt;</font></div><div>or</div><di=
v>=C2=A0 =C2=A0 <font face=3D"monospace, monospace">std::array&lt;void, 3&g=
t;</font></div><div><b><i>ought</i></b> to be permitted by the language.</d=
iv></div></div></div></blockquote></span></div></div></div></blockquote><di=
v><br>They should be permitted and they should be equivalent of `void`.<br>=
</div></blockquote><div><br></div><div>Well, not exactly. They should defin=
itely be permitted, but std::tuple&lt;int, void, int&gt; especially is not =
equivalent to void (the array one can be &quot;equivalent&quot; depending o=
n our equivalence function, but I guess that&#39;s true for anything, thoug=
h it certainly differs on type!). A set that contains one or more null sets=
 is not, itself, a null set. I&#39;m not approximating when I say that void=
 should just be like a user-defined type that has no members and is regular=
.. That really is all that it should be. You should expect tuple&lt;int, voi=
d, int&gt; to behave just like if you had tuple&lt;int, some_user_defined_e=
mpty_type, int&gt;. That&#39;s all it is, and that is what you expect it to=
 be when you are writing generic code. You shouldn&#39;t try to reintroduce=
 special casing. It&#39;s just a type that doesn&#39;t have members.</div><=
div><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;=
border-left:1px #ccc solid;padding-left:1ex"><div>Ok, an empty type or a st=
ateless type is a type that has a state of at least one, because the very e=
xistence of the type creates state. This is why creating a struct of two em=
pty types has the same state as an empty type(ie `1 * 1 =3D 1`) or creating=
 a variant of two empty types has the same state as a boolean(ie `1 + 1 =3D=
 2`). However, `void` is different, and so should be treated as a type with=
 zero state. As such, using `void` as a member to a struct(or `tuple&lt;int=
, void&gt;`) should be equivalent to `void` because `x * 0 =3D 0`. <br></di=
v></blockquote><div><br></div><div>What? No. void is not special here. It&#=
39;s just like any user-defined type without members except it happens to b=
e a built-in type. If you put an instance of your own empty type in a struc=
t, that struct doesn&#39;t become empty. If you don&#39;t see why this hurt=
s things in practice, again, just consider something as simple as a functio=
n that returns the result of N function calls as a tuple of size N. There i=
s nothing logically wrong with this even if one of the functions doesn&#39;=
t have to return a type that contains state. You should be able to access a=
ny of results, iterate over the results, etc. Algorithms on regular types s=
hould simply work on it because there is absolutely no reason, other than m=
anufactured reasons, for why they wouldn&#39;t. void is not special here. I=
t&#39;s just an empty type. Representing it as something less than or diffe=
rent than object types only hurts things.</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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--047d7bd7648ece4cba051c6ba822--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Mon, 3 Aug 2015 10:42:26 -0700
Raw View
--001a113cd41a5d30ac051c6bb1ff
Content-Type: text/plain; charset=UTF-8

On Mon, Aug 3, 2015 at 4:35 AM, Magnus Fromreide <magfr@lysator.liu.se>
wrote:
>
> How should incomplete types other than void, like for example
>
> struct incomplete;
>
> be handled under your proposal, should they get the same new features that
> you
> are proposing for void, or should void be an odd exception?
>

These changes come up because we'd be making void a complete type. It
doesn't affect other incomplete types. User-defined types that are
incomplete would remain incomplete.

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On M=
on, Aug 3, 2015 at 4:35 AM, Magnus Fromreide <span dir=3D"ltr">&lt;<a href=
=3D"mailto:magfr@lysator.liu.se" target=3D"_blank">magfr@lysator.liu.se</a>=
&gt;</span> wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .=
8ex;border-left:1px #ccc solid;padding-left:1ex">How should incomplete type=
s other than void, like for example<br>
<br>
struct incomplete;<br>
<br>
be handled under your proposal, should they get the same new features that =
you<br>
are proposing for void, or should void be an odd exception?<br></blockquote=
><div><br></div><div>These changes come up because we&#39;d be making void =
a complete type. It doesn&#39;t affect other incomplete types. User-defined=
 types that are incomplete would remain incomplete.</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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a113cd41a5d30ac051c6bb1ff--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Mon, 3 Aug 2015 10:45:01 -0700
Raw View
--001a113ccf4a9d2b03051c6bba85
Content-Type: text/plain; charset=UTF-8

On Mon, Aug 3, 2015 at 7:39 AM, Paul Fultz II <pfultz28@gmail.com> wrote:
>
> Probably not. A union with an incomplete type member should be an
> incomplete type
>

We have no reason to change the behavior of unions containing incomplete
types.


> , because it is an yet-to-be-determined size, whereas if the union has a
> void member it should essentially be ignored.
>

A union with a void member shouldn't be ignored. It's a union with a void
member. It is exactly like putting a user-defined type with no members into
a union. There is nothing special here. There is nothing special about any
of these cases. It's just, very simply, an empty type. It is not special.

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On M=
on, Aug 3, 2015 at 7:39 AM, Paul Fultz II <span dir=3D"ltr">&lt;<a href=3D"=
mailto:pfultz28@gmail.com" target=3D"_blank">pfultz28@gmail.com</a>&gt;</sp=
an> wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bord=
er-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Probably not=
.. A union with an incomplete type member should be an incomplete type</div>=
</div></blockquote><div><br></div><div>We have no reason to change the beha=
vior of unions containing incomplete types.</div><div>=C2=A0</div><blockquo=
te class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc so=
lid;padding-left:1ex"><div dir=3D"ltr"><div>, because it is an yet-to-be-de=
termined size, whereas if the union has a void member it should essentially=
 be ignored.<br></div></div></blockquote><div><br></div><div>A union with a=
 void member shouldn&#39;t be ignored. It&#39;s a union with a void member.=
 It is exactly like putting a user-defined type with no members into a unio=
n. There is nothing special here. There is nothing special about any of the=
se cases. It&#39;s just, very simply, an empty type. It is not special.</di=
v></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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a113ccf4a9d2b03051c6bba85--

.


Author: Magnus Fromreide <magfr@lysator.liu.se>
Date: Mon, 3 Aug 2015 20:30:59 +0200
Raw View
On Mon, Aug 03, 2015 at 10:42:26AM -0700, 'Matt Calabrese' via ISO C++ Standard - Future Proposals wrote:
> On Mon, Aug 3, 2015 at 4:35 AM, Magnus Fromreide <magfr@lysator.liu.se>
> wrote:
> >
> > How should incomplete types other than void, like for example
> >
> > struct incomplete;
> >
> > be handled under your proposal, should they get the same new features that
> > you
> > are proposing for void, or should void be an odd exception?
> >
>
> These changes come up because we'd be making void a complete type. It
> doesn't affect other incomplete types. User-defined types that are
> incomplete would remain incomplete.

Would it make sense to only treat void as complete if the definition was
included, like other incomplete types?

void foo; // Error - void is incomplete

#include <void> // Contains compiler magic that "declares" the void type

void bar; // Ok (maybe, depending on the proposal)

The point of this is to allow old programs to continue working as they always
have.

/MF

--

---
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: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Mon, 3 Aug 2015 11:55:11 -0700
Raw View
--001a1142da9c8a88f8051c6cb516
Content-Type: text/plain; charset=UTF-8

On Mon, Aug 3, 2015 at 11:30 AM, Magnus Fromreide <magfr@lysator.liu.se>
wrote:

> On Mon, Aug 03, 2015 at 10:42:26AM -0700, 'Matt Calabrese' via ISO C++
> Standard - Future Proposals wrote:
> > On Mon, Aug 3, 2015 at 4:35 AM, Magnus Fromreide <magfr@lysator.liu.se>
> > wrote:
> > >
> > > How should incomplete types other than void, like for example
> > >
> > > struct incomplete;
> > >
> > > be handled under your proposal, should they get the same new features
> that
> > > you
> > > are proposing for void, or should void be an odd exception?
> > >
> >
> > These changes come up because we'd be making void a complete type. It
> > doesn't affect other incomplete types. User-defined types that are
> > incomplete would remain incomplete.
>
> Would it make sense to only treat void as complete if the definition was
> included, like other incomplete types?
>
> void foo; // Error - void is incomplete
>
> #include <void> // Contains compiler magic that "declares" the void type
>
> void bar; // Ok (maybe, depending on the proposal)
>
> The point of this is to allow old programs to continue working as they
> always
> have.
>

Maybe, but this adds complexity to usage and also can cause subtle bugs.
Worse is that it doesn't really solve the problem in the case where header
files need to include <void>, which they definitely would since template
definitions are what benefit from void being complete. An example of why
this is a problem is, what happens if one header "needs" void to be
incomplete (an old header that does something really weird with SFINAE),
but a different header defines a template and expects void to be complete
so that it can be properly used in generic code? The header with the
template definition would include <void>, and if it just so happens to be
included before the header that expects void to be incomplete, then the
old, odd-ball SFINAE code could break in a subtle way! It will either stop
compiling (good) or compile differently (bad, as you now have ODR
violations in addition to incorrect run time code). A similar kind of
breakage, but perhaps less of a problem, is if the person writing the
template definition simply forgets to include <void>. There, the template
definition then would usually break if someone uses it with void, however,
what if, because of inclusion order, some other header file brought in
<void>? Now that definition would work in that specific translation unit!
Finally, what about the case where a template that wants complete void
needs to invoke a template that expects incomplete void? Here the user is
really out of luck. The same goes for interleaving of include files that
expect void to be complete or void to be incomplete. It would be very
difficult, and some times impossible, to get things to work in this
environment. Instead, I think it makes much more sense to just allow some
breakage here.

I want to restate, though, that I think people are really overestimating
just what would break by making void complete. The standard SFINAE exploits
do not at all rely on void being an incomplete type. We are being generous
here and talking about hypothetical SFINAE exploits that have more accepted
alternatives. Unfortunately, it is considerably difficult to put a number
on if or how much actual real-world code would potentially break, because
the things that would break are very oddball, one-off SFINAE tricks that
you can't really search for. I think the only way to really get an idea of
what could break is to implement complete, regular void in a compiler, and
then go out and compile large projects to see what breaks.

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On M=
on, Aug 3, 2015 at 11:30 AM, Magnus Fromreide <span dir=3D"ltr">&lt;<a href=
=3D"mailto:magfr@lysator.liu.se" target=3D"_blank">magfr@lysator.liu.se</a>=
&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0=
 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class=3D"HOEnZb">=
<div class=3D"h5">On Mon, Aug 03, 2015 at 10:42:26AM -0700, &#39;Matt Calab=
rese&#39; via ISO C++ Standard - Future Proposals wrote:<br>
&gt; On Mon, Aug 3, 2015 at 4:35 AM, Magnus Fromreide &lt;<a href=3D"mailto=
:magfr@lysator.liu.se">magfr@lysator.liu.se</a>&gt;<br>
&gt; wrote:<br>
&gt; &gt;<br>
&gt; &gt; How should incomplete types other than void, like for example<br>
&gt; &gt;<br>
&gt; &gt; struct incomplete;<br>
&gt; &gt;<br>
&gt; &gt; be handled under your proposal, should they get the same new feat=
ures that<br>
&gt; &gt; you<br>
&gt; &gt; are proposing for void, or should void be an odd exception?<br>
&gt; &gt;<br>
&gt;<br>
&gt; These changes come up because we&#39;d be making void a complete type.=
 It<br>
&gt; doesn&#39;t affect other incomplete types. User-defined types that are=
<br>
&gt; incomplete would remain incomplete.<br>
<br>
</div></div>Would it make sense to only treat void as complete if the defin=
ition was<br>
included, like other incomplete types?<br>
<br>
void foo; // Error - void is incomplete<br>
<br>
#include &lt;void&gt; // Contains compiler magic that &quot;declares&quot; =
the void type<br>
<br>
void bar; // Ok (maybe, depending on the proposal)<br>
<br>
The point of this is to allow old programs to continue working as they alwa=
ys<br>
have.<br></blockquote><div><br></div><div>Maybe, but this adds complexity t=
o usage and also can cause subtle bugs. Worse is that it doesn&#39;t really=
 solve the problem in the case where header files need to include &lt;void&=
gt;, which they definitely would since template definitions are what benefi=
t from void being complete. An example of why this is a problem is, what ha=
ppens if one header &quot;needs&quot; void to be incomplete (an old header =
that does something really weird with SFINAE), but a different header defin=
es a template and expects void to be complete so that it can be properly us=
ed in generic code? The header with the template definition would include &=
lt;void&gt;, and if it just so happens to be included before the header tha=
t expects void to be incomplete, then the old, odd-ball SFINAE code could b=
reak in a subtle way! It will either stop compiling (good) or compile diffe=
rently (bad, as you now have ODR violations in addition to incorrect run ti=
me code). A similar kind of breakage, but perhaps less of a problem, is if =
the person writing the template definition simply forgets to include &lt;vo=
id&gt;. There, the template definition then would usually break if someone =
uses it with void, however, what if, because of inclusion order, some other=
 header file brought in &lt;void&gt;? Now that definition would work in tha=
t specific translation unit! Finally, what about the case where a template =
that wants complete void needs to invoke a template that expects incomplete=
 void? Here the user is really out of luck. The same goes for interleaving =
of include files that expect void to be complete or void to be incomplete. =
It would be very difficult, and some times impossible, to get things to wor=
k in this environment. Instead, I think it makes much more sense to just al=
low some breakage here.</div><div><br></div><div>I want to restate, though,=
 that I think people are really overestimating just what would break by mak=
ing void complete. The standard SFINAE exploits do not at all rely on void =
being an incomplete type. We are being generous here and talking about hypo=
thetical SFINAE exploits that have more accepted alternatives. Unfortunatel=
y, it is considerably difficult to put a number on if or how much actual re=
al-world code would potentially break, because the things that would break =
are very oddball, one-off SFINAE tricks that you can&#39;t really search fo=
r. I think the only way to really get an idea of what could break is to imp=
lement complete, regular void in a compiler, and then go out and compile la=
rge projects to see what breaks.</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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a1142da9c8a88f8051c6cb516--

.


Author: Paul Fultz II <pfultz28@gmail.com>
Date: Mon, 3 Aug 2015 13:38:43 -0700 (PDT)
Raw View
------=_Part_629_591000707.1438634323674
Content-Type: multipart/alternative;
 boundary="----=_Part_630_989482281.1438634323675"

------=_Part_630_989482281.1438634323675
Content-Type: text/plain; charset=UTF-8



On Monday, August 3, 2015 at 12:40:04 PM UTC-5, Matt Calabrese wrote:
>
> On Mon, Aug 3, 2015 at 2:58 AM, Paul Fultz II <pful...@gmail.com
> <javascript:>> wrote:
>
>>
>>
>> On Monday, August 3, 2015 at 1:02:46 AM UTC-5, Matt Calabrese wrote:
>>>
>>> On Sun, Aug 2, 2015 at 9:41 PM, Arthur O'Dwyer <arthur....@gmail.com>
>>> wrote:
>>>
>>>> On Sun, Aug 2, 2015 at 8:46 PM, 'Matt Calabrese' via ISO C++ Standard -
>>>> Future Proposals <std-pr...@isocpp.org> wrote:
>>>>
>>>>>
>>>>> As far as possible usage of void as a means to cause substitution to
>>>>> fail by way of making a function have a void parameter, I find that more
>>>>> compelling, and yes, that can potentially cause some code to change in
>>>>> observable behavior. For that case, however, whether or not sizeof works
>>>>> for void has absolutely no bearing. That case would necessarily break since
>>>>> passing of void or reference-to-void is one of the more common things to
>>>>> come up in generic code that we'd like to fix (It's the primary reason we
>>>>> need a std::promise<void> specialization, for example, or see my tuple
>>>>> example, or, in the more abstract, any generic code where you need to
>>>>> invoke a function with an instance of a type that is dependent on a
>>>>> template parameter where that type may or may not be void).
>>>>>
>>>>
>>>> I think it's extremely debatable whether
>>>>     std::tuple<int, void, int>
>>>> or
>>>>     std::array<void, 3>
>>>> *ought* to be permitted by the language.
>>>>
>>>
>> They should be permitted and they should be equivalent of `void`.
>>
>
> Well, not exactly. They should definitely be permitted, but
> std::tuple<int, void, int> especially is not equivalent to void (the array
> one can be "equivalent" depending on our equivalence function, but I guess
> that's true for anything, though it certainly differs on type!). A set that
> contains one or more null sets is not, itself, a null set.
>

We aren't talking about sets. We are talking about states in a program(or
typesystem rather). A `struct` or `tuple` is the product of the states of
its members. If you define a struct with a member that has zero state, the
resulting struct will have zero state as well.


> I'm not approximating when I say that void should just be like a
> user-defined type that has no members and is regular. That really is all
> that it should be. You should expect tuple<int, void, int> to behave just
> like if you had tuple<int, some_user_defined_empty_type, int>. That's all
> it is, and that is what you expect it to be when you are writing generic
> code. You shouldn't try to reintroduce special casing. It's just a type
> that doesn't have members.
>

I thought the point was to embrace zero. Instead, you want to define `void`
with one state rather than zero state. I don't think that is very sound at
all.


>
> Ok, an empty type or a stateless type is a type that has a state of at
>> least one, because the very existence of the type creates state. This is
>> why creating a struct of two empty types has the same state as an empty
>> type(ie `1 * 1 = 1`) or creating a variant of two empty types has the same
>> state as a boolean(ie `1 + 1 = 2`). However, `void` is different, and so
>> should be treated as a type with zero state. As such, using `void` as a
>> member to a struct(or `tuple<int, void>`) should be equivalent to `void`
>> because `x * 0 = 0`.
>>
>
> What? No. void is not special here. It's just like any user-defined type
> without members except it happens to be a built-in type. If you put an
> instance of your own empty type in a struct, that struct doesn't become
> empty. If you don't see why this hurts things in practice, again, just
> consider something as simple as a function that returns the result of N
> function calls as a tuple of size N.
>

If one of the functions return `void` then the function should return
`void`.


> There is nothing logically wrong with this even if one of the functions
> doesn't have to return a type that contains state. You should be able to
> access any of results, iterate over the results, etc. Algorithms on regular
> types should simply work on it because there is absolutely no reason, other
> than manufactured reasons, for why they wouldn't. void is not special here.
> It's just an empty type. Representing it as something less than or
> different than object types only hurts things.
>


But by doing that, you are now injecting extra state into the program.
Perhaps, that is acceptable for your use case, in which it would be better
for the user to explicity transform`void` to an empty type, rather than
silently inject extra state.

--

---
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_630_989482281.1438634323675
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<br><br>On Monday, August 3, 2015 at 12:40:04 PM UTC-5, Matt Calabrese wrot=
e:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;b=
order-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div c=
lass=3D"gmail_quote">On Mon, Aug 3, 2015 at 2:58 AM, Paul Fultz II <span di=
r=3D"ltr">&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mail=
to=3D"omS4gA6iDwAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javasc=
ript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;retur=
n true;">pful...@gmail.com</a>&gt;</span> wrote:<br><blockquote class=3D"gm=
ail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-le=
ft:1ex"><br><br>On Monday, August 3, 2015 at 1:02:46 AM UTC-5, Matt Calabre=
se 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><div=
 class=3D"gmail_quote">On Sun, Aug 2, 2015 at 9:41 PM, Arthur O&#39;Dwyer <=
span dir=3D"ltr">&lt;<a rel=3D"nofollow">arthur....@gmail.com</a>&gt;</span=
> wrote:<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"><span>On =
Sun, Aug 2, 2015 at 8:46 PM, &#39;Matt Calabrese&#39; via ISO C++ Standard =
- Future Proposals <span dir=3D"ltr">&lt;<a rel=3D"nofollow">std-pr...@isoc=
pp.org</a>&gt;</span> wrote:<br></span><div><div class=3D"gmail_quote"><spa=
n><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><div class=3D"gmail_=
quote"><br></div></div></div></blockquote><blockquote class=3D"gmail_quote"=
 style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv dir=3D"ltr"><div><div class=3D"gmail_quote"><div>As far as possible usag=
e of void as a means to cause substitution to fail by way of making a funct=
ion have a void parameter, I find that more compelling, and yes, that can p=
otentially cause some code to change in observable behavior. For that case,=
 however, whether or not sizeof works for void has absolutely no bearing. T=
hat case would necessarily break since passing of void or reference-to-void=
 is one of the more common things to come up in generic code that we&#39;d =
like to fix (It&#39;s the primary reason we need a std::promise&lt;void&gt;=
 specialization, for example, or see my tuple example, or, in the more abst=
ract, any generic code where you need to invoke a function with an instance=
 of a type that is dependent on a template parameter where that type may or=
 may not be void).<br></div></div></div></div></blockquote><div><br></div><=
/span><div>I think it&#39;s extremely debatable whether</div><div>=C2=A0 =
=C2=A0 <font face=3D"monospace, monospace">std::tuple&lt;int, void, int&gt;=
</font></div><div>or</div><div>=C2=A0 =C2=A0 <font face=3D"monospace, monos=
pace">std::array&lt;void, 3&gt;</font></div><div><b><i>ought</i></b> to be =
permitted by the language.</div></div></div></div></blockquote></span></div=
></div></div></blockquote><div><br>They should be permitted and they should=
 be equivalent of `void`.<br></div></blockquote><div><br></div><div>Well, n=
ot exactly. They should definitely be permitted, but std::tuple&lt;int, voi=
d, int&gt; especially is not equivalent to void (the array one can be &quot=
;equivalent&quot; depending on our equivalence function, but I guess that&#=
39;s true for anything, though it certainly differs on type!). A set that c=
ontains one or more null sets is not, itself, a null set.</div></div></div>=
</div></blockquote><div><br>We aren&#39;t talking about sets. We are talkin=
g about states in a program(or typesystem rather). A `struct` or `tuple` is=
 the product of the states of its members. If you define a struct with a me=
mber that has zero state, the resulting struct will have zero state as well=
..<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr"><div><div class=3D"gmail_quote"><div> I&#39;m not approximating when I =
say that void should just be like a user-defined type that has no members a=
nd is regular. That really is all that it should be. You should expect tupl=
e&lt;int, void, int&gt; to behave just like if you had tuple&lt;int, some_u=
ser_defined_empty_type, int&gt;. That&#39;s all it is, and that is what you=
 expect it to be when you are writing generic code. You shouldn&#39;t try t=
o reintroduce special casing. It&#39;s just a type that doesn&#39;t have me=
mbers.</div></div></div></div></blockquote><div><br>I thought the point was=
 to embrace zero. Instead, you want to define `void` with one state rather =
than zero state. I don&#39;t think that is very sound at all.<br>=C2=A0</di=
v><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;b=
order-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div c=
lass=3D"gmail_quote"><div><br></div><blockquote class=3D"gmail_quote" style=
=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>Ok,=
 an empty type or a stateless type is a type that has a state of at least o=
ne, because the very existence of the type creates state. This is why creat=
ing a struct of two empty types has the same state as an empty type(ie `1 *=
 1 =3D 1`) or creating a variant of two empty types has the same state as a=
 boolean(ie `1 + 1 =3D 2`). However, `void` is different, and so should be =
treated as a type with zero state. As such, using `void` as a member to a s=
truct(or `tuple&lt;int, void&gt;`) should be equivalent to `void` because `=
x * 0 =3D 0`. <br></div></blockquote><div><br></div><div>What? No. void is =
not special here. It&#39;s just like any user-defined type without members =
except it happens to be a built-in type. If you put an instance of your own=
 empty type in a struct, that struct doesn&#39;t become empty. If you don&#=
39;t see why this hurts things in practice, again, just consider something =
as simple as a function that returns the result of N function calls as a tu=
ple of size N. </div></div></div></div></blockquote><div><br>If one of the =
functions return `void` then the function should return `void`.<br>=C2=A0</=
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>There is nothing logically wrong with this even=
 if one of the functions doesn&#39;t have to return a type that contains st=
ate. You should be able to access any of results, iterate over the results,=
 etc. Algorithms on regular types should simply work on it because there is=
 absolutely no reason, other than manufactured reasons, for why they wouldn=
&#39;t. void is not special here. It&#39;s just an empty type. Representing=
 it as something less than or different than object types only hurts things=
..</div></div></div></div></blockquote><div><br><br>But by doing that, you a=
re now injecting extra state into the program. Perhaps, that is acceptable =
for your use case, in which it would be better for the user to explicity tr=
ansform`void` to an empty type, rather than silently inject extra state. <b=
r></div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_630_989482281.1438634323675--
------=_Part_629_591000707.1438634323674--

.


Author: Zach Laine <whatwasthataddress@gmail.com>
Date: Mon, 3 Aug 2015 15:47:50 -0500
Raw View
--f46d04430440695c4f051c6e4872
Content-Type: text/plain; charset=UTF-8

On Mon, Aug 3, 2015 at 3:38 PM, Paul Fultz II <pfultz28@gmail.com> wrote:

[snip]


> What? No. void is not special here. It's just like any user-defined type
>> without members except it happens to be a built-in type. If you put an
>> instance of your own empty type in a struct, that struct doesn't become
>> empty. If you don't see why this hurts things in practice, again, just
>> consider something as simple as a function that returns the result of N
>> function calls as a tuple of size N.
>>
>
> If one of the functions return `void` then the function should return
> `void`.
>
>
>> There is nothing logically wrong with this even if one of the functions
>> doesn't have to return a type that contains state. You should be able to
>> access any of results, iterate over the results, etc. Algorithms on regular
>> types should simply work on it because there is absolutely no reason, other
>> than manufactured reasons, for why they wouldn't. void is not special here.
>> It's just an empty type. Representing it as something less than or
>> different than object types only hurts things.
>>
>
>
> But by doing that, you are now injecting extra state into the program.
> Perhaps, that is acceptable for your use case, in which it would be better
> for the user to explicity transform`void` to an empty type, rather than
> silently inject extra state.
>

What extra state is injected?  If I return a byte-sized void with an
undefined value that should be ignored, but you choose not to ignore it,
what can you do with it?  You can't read its value -- it's empty.  What is
the outward change to your program that I will observe?

Zach

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On M=
on, Aug 3, 2015 at 3:38 PM, Paul Fultz II <span dir=3D"ltr">&lt;<a href=3D"=
mailto:pfultz28@gmail.com" target=3D"_blank">pfultz28@gmail.com</a>&gt;</sp=
an> wrote:<br><div><br></div><div>[snip]</div><div>=C2=A0</div><blockquote =
class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid=
;padding-left:1ex"><span class=3D""><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>What? No. void is no=
t special here. It&#39;s just like any user-defined type without members ex=
cept it happens to be a built-in type. If you put an instance of your own e=
mpty type in a struct, that struct doesn&#39;t become empty. If you don&#39=
;t see why this hurts things in practice, again, just consider something as=
 simple as a function that returns the result of N function calls as a tupl=
e of size N. </div></div></div></div></blockquote></span><div><br>If one of=
 the functions return `void` then the function should return `void`.<br>=C2=
=A0</div><span class=3D""><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>There is nothing logically wr=
ong with this even if one of the functions doesn&#39;t have to return a typ=
e that contains state. You should be able to access any of results, iterate=
 over the results, etc. Algorithms on regular types should simply work on i=
t because there is absolutely no reason, other than manufactured reasons, f=
or why they wouldn&#39;t. void is not special here. It&#39;s just an empty =
type. Representing it as something less than or different than object types=
 only hurts things.</div></div></div></div></blockquote></span><div><br><br=
>But by doing that, you are now injecting extra state into the program. Per=
haps, that is acceptable for your use case, in which it would be better for=
 the user to explicity transform`void` to an empty type, rather than silent=
ly inject extra state.=C2=A0</div></blockquote><div><br></div><div>What ext=
ra state is injected?=C2=A0 If I return a byte-sized void with an undefined=
 value that should be ignored, but you choose not to ignore it, what can yo=
u do with it?=C2=A0=C2=A0You can&#39;t read its value -- it&#39;s empty.=C2=
=A0=C2=A0What is the outward change to your program that I will observe?</d=
iv><div><br></div><div>Zach</div><div><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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--f46d04430440695c4f051c6e4872--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Mon, 3 Aug 2015 13:51:36 -0700
Raw View
--001a1142da9cec0cfd051c6e55a0
Content-Type: text/plain; charset=UTF-8

On Mon, Aug 3, 2015 at 1:38 PM, Paul Fultz II <pfultz28@gmail.com> wrote:

>
>
> On Monday, August 3, 2015 at 12:40:04 PM UTC-5, Matt Calabrese wrote:
>>
>> On Mon, Aug 3, 2015 at 2:58 AM, Paul Fultz II <pful...@gmail.com> wrote:
>>
>>>
>>>
>>> On Monday, August 3, 2015 at 1:02:46 AM UTC-5, Matt Calabrese wrote:
>>>>
>>>> On Sun, Aug 2, 2015 at 9:41 PM, Arthur O'Dwyer <arthur....@gmail.com>
>>>> wrote:
>>>>
>>>>> On Sun, Aug 2, 2015 at 8:46 PM, 'Matt Calabrese' via ISO C++ Standard
>>>>> - Future Proposals <std-pr...@isocpp.org> wrote:
>>>>>
>>>>>>
>>>>>> As far as possible usage of void as a means to cause substitution to
>>>>>> fail by way of making a function have a void parameter, I find that more
>>>>>> compelling, and yes, that can potentially cause some code to change in
>>>>>> observable behavior. For that case, however, whether or not sizeof works
>>>>>> for void has absolutely no bearing. That case would necessarily break since
>>>>>> passing of void or reference-to-void is one of the more common things to
>>>>>> come up in generic code that we'd like to fix (It's the primary reason we
>>>>>> need a std::promise<void> specialization, for example, or see my tuple
>>>>>> example, or, in the more abstract, any generic code where you need to
>>>>>> invoke a function with an instance of a type that is dependent on a
>>>>>> template parameter where that type may or may not be void).
>>>>>>
>>>>>
>>>>> I think it's extremely debatable whether
>>>>>     std::tuple<int, void, int>
>>>>> or
>>>>>     std::array<void, 3>
>>>>> *ought* to be permitted by the language.
>>>>>
>>>>
>>> They should be permitted and they should be equivalent of `void`.
>>>
>>
>> Well, not exactly. They should definitely be permitted, but
>> std::tuple<int, void, int> especially is not equivalent to void (the array
>> one can be "equivalent" depending on our equivalence function, but I guess
>> that's true for anything, though it certainly differs on type!). A set that
>> contains one or more null sets is not, itself, a null set.
>>
>
> We aren't talking about sets.
>

It's a metaphor. We are talking about something, in this case a tuple, that
contains members. A tuple that contains an int and an instance of a type
that just so happens to have not datamembers, does not all of a sudden
imply that the tuple is somehow void. That makes no sense. The tuple has
two members. An int and a type that has no members. That is all. There is
nothing special here.

I thought the point was to embrace zero. Instead, you want to define `void`
> with one state rather than zero state. I don't think that is very sound at
> all.
>

What are you talking about? If you want to understand why things are the
way the are, you should think about it in comparison to types that have
data. In other words, A type with 2 members, vs. a type with 1 member, vs.
a type with 0 members (any user-defined type with no members, or in this
case, void).


> If one of the functions return `void` then the function should return
> `void`.
>

That doesn't make any sense and isn't consistent with the rest of the
language. You want a tuple of the results. The first function returns an
int, the second returns void, the third returns int. The result is a
tuple<int, void, int>. Your logic for why the result should be "void" and
not tuple<int, void, int>, where you can access each individual component,
is completely flawed. All void is is an empty type.

But by doing that, you are now injecting extra state into the program.
> Perhaps, that is acceptable for your use case, in which it would be better
> for the user to explicity transform`void` to an empty type, rather than
> silently inject extra state.
>

What?

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On M=
on, Aug 3, 2015 at 1:38 PM, Paul Fultz II <span dir=3D"ltr">&lt;<a href=3D"=
mailto:pfultz28@gmail.com" target=3D"_blank">pfultz28@gmail.com</a>&gt;</sp=
an> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;=
border-left:1px #ccc solid;padding-left:1ex"><br><br>On Monday, August 3, 2=
015 at 12:40:04 PM UTC-5, Matt Calabrese wrote:<span class=3D""><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_quot=
e">On Mon, Aug 3, 2015 at 2:58 AM, Paul Fultz II <span dir=3D"ltr">&lt;<a r=
el=3D"nofollow">pful...@gmail.com</a>&gt;</span> wrote:<br><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;pad=
ding-left:1ex"><br><br>On Monday, August 3, 2015 at 1:02:46 AM UTC-5, Matt =
Calabrese 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"><d=
iv><div class=3D"gmail_quote">On Sun, Aug 2, 2015 at 9:41 PM, Arthur O&#39;=
Dwyer <span dir=3D"ltr">&lt;<a rel=3D"nofollow">arthur....@gmail.com</a>&gt=
;</span> wrote:<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"><s=
pan>On Sun, Aug 2, 2015 at 8:46 PM, &#39;Matt Calabrese&#39; via ISO C++ St=
andard - Future Proposals <span dir=3D"ltr">&lt;<a rel=3D"nofollow">std-pr.=
...@isocpp.org</a>&gt;</span> wrote:<br></span><div><div class=3D"gmail_quot=
e"><span><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><div class=3D=
"gmail_quote"><br></div></div></div></blockquote><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><div class=3D"gmail_quote"><div>As far as possib=
le usage of void as a means to cause substitution to fail by way of making =
a function have a void parameter, I find that more compelling, and yes, tha=
t can potentially cause some code to change in observable behavior. For tha=
t case, however, whether or not sizeof works for void has absolutely no bea=
ring. That case would necessarily break since passing of void or reference-=
to-void is one of the more common things to come up in generic code that we=
&#39;d like to fix (It&#39;s the primary reason we need a std::promise&lt;v=
oid&gt; specialization, for example, or see my tuple example, or, in the mo=
re abstract, any generic code where you need to invoke a function with an i=
nstance of a type that is dependent on a template parameter where that type=
 may or may not be void).<br></div></div></div></div></blockquote><div><br>=
</div></span><div>I think it&#39;s extremely debatable whether</div><div>=
=C2=A0 =C2=A0 <font face=3D"monospace, monospace">std::tuple&lt;int, void, =
int&gt;</font></div><div>or</div><div>=C2=A0 =C2=A0 <font face=3D"monospace=
, monospace">std::array&lt;void, 3&gt;</font></div><div><b><i>ought</i></b>=
 to be permitted by the language.</div></div></div></div></blockquote></spa=
n></div></div></div></blockquote><div><br>They should be permitted and they=
 should be equivalent of `void`.<br></div></blockquote><div><br></div><div>=
Well, not exactly. They should definitely be permitted, but std::tuple&lt;i=
nt, void, int&gt; especially is not equivalent to void (the array one can b=
e &quot;equivalent&quot; depending on our equivalence function, but I guess=
 that&#39;s true for anything, though it certainly differs on type!). A set=
 that contains one or more null sets is not, itself, a null set.</div></div=
></div></div></blockquote></span><div><br>We aren&#39;t talking about sets.=
</div></blockquote><div><br></div><div>It&#39;s a metaphor. We are talking =
about something, in this case a tuple, that contains members. A tuple that =
contains an int and an instance of a type that just so happens to have not =
datamembers, does not all of a sudden imply that the tuple is somehow void.=
 That makes no sense. The tuple has two members. An int and a type that has=
 no members. That is all. There is nothing special here.</div><div><br></di=
v><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:=
1px #ccc solid;padding-left:1ex"><div>I thought the point was to embrace ze=
ro. Instead, you want to define `void` with one state rather than zero stat=
e. I don&#39;t think that is very sound at all.<br></div></blockquote><div>=
<br></div><div>What are you talking about? If you want to understand why th=
ings are the way the are, you should think about it in comparison to types =
that have data. In other words, A type with 2 members, vs. a type with 1 me=
mber, vs. a type with 0 members (any user-defined type with no members, or =
in this case, void).</div><div>=C2=A0</div><blockquote class=3D"gmail_quote=
" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><=
div>If one of the functions return `void` then the function should return `=
void`.<br></div></blockquote><div><br></div><div>That doesn&#39;t make any =
sense and isn&#39;t consistent with the rest of the language. You want a tu=
ple of the results. The first function returns an int, the second returns v=
oid, the third returns int. The result is a tuple&lt;int, void, int&gt;. Yo=
ur logic for why the result should be &quot;void&quot; and not tuple&lt;int=
, void, int&gt;, where you can access each individual component, is complet=
ely flawed. All void is is an empty type.</div><div><br></div><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;=
padding-left:1ex"><div>But by doing that, you are now injecting extra state=
 into the program. Perhaps, that is acceptable for your use case, in which =
it would be better for the user to explicity transform`void` to an empty ty=
pe, rather than silently inject extra state.</div></blockquote><div><br></d=
iv><div>What?<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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a1142da9cec0cfd051c6e55a0--

.


Author: Paul Fultz II <pfultz28@gmail.com>
Date: Mon, 3 Aug 2015 15:57:33 -0700 (PDT)
Raw View
------=_Part_1155_2077304799.1438642653344
Content-Type: multipart/alternative;
 boundary="----=_Part_1156_1458999706.1438642653345"

------=_Part_1156_1458999706.1438642653345
Content-Type: text/plain; charset=UTF-8



On Monday, August 3, 2015 at 3:47:52 PM UTC-5, Zach Laine wrote:
>
> On Mon, Aug 3, 2015 at 3:38 PM, Paul Fultz II <pful...@gmail.com
> <javascript:>> wrote:
>
> [snip]
>
>
>> What? No. void is not special here. It's just like any user-defined type
>>> without members except it happens to be a built-in type. If you put an
>>> instance of your own empty type in a struct, that struct doesn't become
>>> empty. If you don't see why this hurts things in practice, again, just
>>> consider something as simple as a function that returns the result of N
>>> function calls as a tuple of size N.
>>>
>>
>> If one of the functions return `void` then the function should return
>> `void`.
>>
>>
>>> There is nothing logically wrong with this even if one of the functions
>>> doesn't have to return a type that contains state. You should be able to
>>> access any of results, iterate over the results, etc. Algorithms on regular
>>> types should simply work on it because there is absolutely no reason, other
>>> than manufactured reasons, for why they wouldn't. void is not special here.
>>> It's just an empty type. Representing it as something less than or
>>> different than object types only hurts things.
>>>
>>
>>
>> But by doing that, you are now injecting extra state into the program.
>> Perhaps, that is acceptable for your use case, in which it would be better
>> for the user to explicity transform`void` to an empty type, rather than
>> silently inject extra state.
>>
>
> What extra state is injected?  If I return a byte-sized void with an
> undefined value that should be ignored, but you choose not to ignore it,
> what can you do with it?  You can't read its value -- it's empty.  What is
> the outward change to your program that I will observe?
>

Well, for the case of a tuple it doesn't inject extra state(because `x * 1
= 1`). However, it can be observed for sum types. A type of boolean has two
states. You can easily sum two empty states together(ie variant<empty1,
empty2>) to achieve two states like a boolean, but you shouldn't be able to
achieve this with `variant<emtpy, void>`. Here's why ,say for example you
had a variant that represent the call back of two functions:

struct empty
{};

void f();
empty g();

variant<void, empty> foo(bool pick_f)
{
    if (pick_f) return f();
    else return g();
}

So when I call `foo` it will return the result of either `f()` or `g()`.
However, the result of `f()` has no state, so therfore the visit to the
result of foo should have just one overload:

variant<void, empty> v = foo(i);
v.visit([](empty) { std::cout << "I'm always 'empty'"; });




>
> Zach
>
>

--

---
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_1156_1458999706.1438642653345
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<br><br>On Monday, August 3, 2015 at 3:47:52 PM UTC-5, Zach Laine wrote:<bl=
ockquote 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">On Mon, Aug 3, 2015 at 3:38 PM, Paul Fultz II <span dir=3D=
"ltr">&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=
=3D"jUOEL06sDwAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascri=
pt:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return =
true;">pful...@gmail.com</a>&gt;</span> wrote:<br><div><br></div><div>[snip=
]</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0=
 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span><blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #cc=
c solid;padding-left:1ex"><div dir=3D"ltr"><div><div class=3D"gmail_quote">=
<div>What? No. void is not special here. It&#39;s just like any user-define=
d type without members except it happens to be a built-in type. If you put =
an instance of your own empty type in a struct, that struct doesn&#39;t bec=
ome empty. If you don&#39;t see why this hurts things in practice, again, j=
ust consider something as simple as a function that returns the result of N=
 function calls as a tuple of size N. </div></div></div></div></blockquote>=
</span><div><br>If one of the functions return `void` then the function sho=
uld return `void`.<br>=C2=A0</div><span><blockquote class=3D"gmail_quote" s=
tyle=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>There is nothing=
 logically wrong with this even if one of the functions doesn&#39;t have to=
 return a type that contains state. You should be able to access any of res=
ults, iterate over the results, etc. Algorithms on regular types should sim=
ply work on it because there is absolutely no reason, other than manufactur=
ed reasons, for why they wouldn&#39;t. void is not special here. It&#39;s j=
ust an empty type. Representing it as something less than or different than=
 object types only hurts things.</div></div></div></div></blockquote></span=
><div><br><br>But by doing that, you are now injecting extra state into the=
 program. Perhaps, that is acceptable for your use case, in which it would =
be better for the user to explicity transform`void` to an empty type, rathe=
r than silently inject extra state.=C2=A0</div></blockquote><div><br></div>=
<div>What extra state is injected?=C2=A0 If I return a byte-sized void with=
 an undefined value that should be ignored, but you choose not to ignore it=
, what can you do with it?=C2=A0=C2=A0You can&#39;t read its value -- it&#3=
9;s empty.=C2=A0=C2=A0What is the outward change to your program that I wil=
l observe?</div></div></div></div></blockquote><div><br>Well, for the case =
of a tuple it doesn&#39;t inject extra state(because `x * 1 =3D 1`). Howeve=
r, it can be observed for sum types. A type of boolean has two states. You =
can easily sum two empty states=20
together(ie variant&lt;empty1, empty2&gt;) to achieve two states like a=20
boolean, but you shouldn&#39;t be able to achieve this with `variant&lt;emt=
py, void&gt;`. Here&#39;s why ,say for example you had a variant that repre=
sent the call back of two functions:<br><br>struct empty<br>{};<br><br>void=
 f();<br>empty g();<br><br>variant&lt;void, empty&gt; foo(bool pick_f)<br>{=
<br>=C2=A0=C2=A0=C2=A0 if (pick_f) return f();<br>=C2=A0=C2=A0=C2=A0 else r=
eturn g();<br>}<br><br>So when I call `foo` it will return the result of ei=
ther `f()` or `g()`. However, the result of `f()` has no state, so therfore=
 the visit to the result of foo should have just one overload:<br><br>varia=
nt&lt;void, empty&gt; v =3D foo(i);<br>v.visit([](empty) { std::cout &lt;&l=
t; &quot;I&#39;m always &#39;empty&#39;&quot;; });<br><br><br>=C2=A0</div><=
blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bord=
er-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div clas=
s=3D"gmail_quote"><div><br></div><div>Zach</div><div><br></div></div></div>=
</div>
</blockquote>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_1156_1458999706.1438642653345--
------=_Part_1155_2077304799.1438642653344--

.


Author: Paul Fultz II <pfultz28@gmail.com>
Date: Mon, 3 Aug 2015 16:06:36 -0700 (PDT)
Raw View
------=_Part_1123_1160685786.1438643196745
Content-Type: multipart/alternative;
 boundary="----=_Part_1124_1685925669.1438643196746"

------=_Part_1124_1685925669.1438643196746
Content-Type: text/plain; charset=UTF-8



>
> Well, for the case of a tuple it doesn't inject extra state(because `x * 1
> = 1`).
>

I meant to write `x * 1 = x`, of course.


--

---
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_1124_1685925669.1438643196746
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div><br>=
Well, for the case of a tuple it doesn&#39;t inject extra state(because `x =
* 1 =3D 1`). </div></blockquote><div><br>I meant to write `x * 1 =3D x`, of=
 course.<br>=C2=A0</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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_1124_1685925669.1438643196746--
------=_Part_1123_1160685786.1438643196745--

.


Author: Edward Catmur <ed@catmur.co.uk>
Date: Mon, 3 Aug 2015 16:17:04 -0700 (PDT)
Raw View
------=_Part_2371_401099598.1438643824794
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

I think the confusion here is over whether void should be more like the zer=
o type or the unit type. Sean's mention of zero could be construed as a vot=
e in favor of the former, but I think the rest of what he wrote indicates t=
hat he's in fact arguing for void as the unit type. Paul appears to be in f=
avor of void as the zero type.

For what it's worth, I think we have enough unit types in C++ already, and =
don't see why we need one more. At the same time, void is clearly not the z=
ero type - a function returning zero is a function that does not return.=20

--=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_2371_401099598.1438643824794--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Mon, 3 Aug 2015 16:36:24 -0700
Raw View
--089e0149c77a4b7603051c70a326
Content-Type: text/plain; charset=UTF-8

On Mon, Aug 3, 2015 at 3:57 PM, Paul Fultz II <pfultz28@gmail.com> wrote:
>
> Well, for the case of a tuple it doesn't inject extra state(because `x * 1
> = 1`). However, it can be observed for sum types. A type of boolean has two
> states. You can easily sum two empty states together(ie variant<empty1,
> empty2>) to achieve two states like a boolean, but you shouldn't be able to
> achieve this with `variant<emtpy, void>`. Here's why ,say for example you
> had a variant that represent the call back of two functions:
>
> struct empty
> {};
>
> void f();
> empty g();
>
> variant<void, empty> foo(bool pick_f)
> {
>     if (pick_f) return f();
>     else return g();
> }
>
> So when I call `foo` it will return the result of either `f()` or `g()`.
> However, the result of `f()` has no state, so therfore the visit to the
> result of foo should have just one overload:
>

No it shouldn't, the visitor should handle the void state. There is no
reason to treat void as special here and not doing so prevents you from
using such constructs in real generic code (not to mention that it means
variant has an arbitrary special case). void is just a type like your
struct empty{}. It just happens to be a built-in type rather than a
user-defined type. You are gaining nothing by trying to make it something
else and you are only making it harder to properly use in generic code.

variant<void, empty> v = foo(i);
> v.visit([](empty) { std::cout << "I'm always 'empty'"; });
>

Why do you make such a claim? You've explicitly stated that you can contain
void here in the parameter list of variant, and so your visitor should
handle it in the visitation. It's nothing special. If you didn't want to
handle it, you simply wouldn't put it in the variant. Just to keep things
grounded with more practical examples, let's say that your function "foo"
is generic code living on a server and is reacting to a remote invocation
request. It invokes "f" or it invokes "g" based on the information in the
request (i.e. the function name and serialized arguments) and it locally
returns the result so that the calling-code can send a message back to the
client. All that the caller of "foo" does with the result is visit it with
a generic lambda that serializes the result that is contained and sends it
back to the client. If one of the functions happened to have a return type
of void, then so what? The serialization part of your visitation might be a
null op, or it might contain type info, or anything at all, but it still
sends back a message so that the client knows the call went through.
Everything just works because void is nothing special here, and there is
nothing logically incorrect with doing this in the visitor. You're just
sending back a reply with the result -- it just so happens that the type
may be one with no members. If you arbitrarily special-case void for
variant in such a way that it corresponds to a lack of a member, rather
than an empty member, then your visitation doesn't handle the void case and
your client never receives the reply. This isn't some strange, contrived
case and you will find that this kind of thing comes up a lot when you are
dealing with function results in generic code. This very scenario is
strikingly similar to code I've written and is in use, and is not
particularly unique. Right now, there is extra indirection to handle the
void case, but it simply should not be necessary when you think about the
problem in the abstract. The same is true for all generic code where you
are dealing with a dependent type that may or may not be void and you need
to pass along whatever state is there (which may be state that contains
nothing, such as void).

If you don't buy into such explanations and real-world examples, then
exactly what code do you have in mind that benefits from the behavior that
you suggest? I understand that you're defining what you feel it should do,
which seems to be different from any other type in the language, and yet I
see no practical rationale or real-world code to show why this would ever
be desired. As far as I can see, it just prevents people from easily
writing generic code and keeps people having to make strange workarounds
for void.

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On M=
on, Aug 3, 2015 at 3:57 PM, Paul Fultz II <span dir=3D"ltr">&lt;<a href=3D"=
mailto:pfultz28@gmail.com" target=3D"_blank">pfultz28@gmail.com</a>&gt;</sp=
an> wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bord=
er-left:1px #ccc solid;padding-left:1ex"><div>Well, for the case of a tuple=
 it doesn&#39;t inject extra state(because `x * 1 =3D 1`). However, it can =
be observed for sum types. A type of boolean has two states. You can easily=
 sum two empty states=20
together(ie variant&lt;empty1, empty2&gt;) to achieve two states like a=20
boolean, but you shouldn&#39;t be able to achieve this with `variant&lt;emt=
py, void&gt;`. Here&#39;s why ,say for example you had a variant that repre=
sent the call back of two functions:<br><br>struct empty<br>{};<br><br>void=
 f();<br>empty g();<br><br>variant&lt;void, empty&gt; foo(bool pick_f)<br>{=
<br>=C2=A0=C2=A0=C2=A0 if (pick_f) return f();<br>=C2=A0=C2=A0=C2=A0 else r=
eturn g();<br>}<br><br>So when I call `foo` it will return the result of ei=
ther `f()` or `g()`. However, the result of `f()` has no state, so therfore=
 the visit to the result of foo should have just one overload:<br></div></b=
lockquote><div><br></div><div>No it shouldn&#39;t, the visitor should handl=
e the void state. There is no reason to treat void as special here and not =
doing so prevents you from using such constructs in real generic code (not =
to mention that it means variant has an arbitrary special case). void is ju=
st a type like your struct empty{}. It just happens to be a built-in type r=
ather than a user-defined type. You are gaining nothing by trying to make i=
t something else and you are only making it harder to properly use in gener=
ic code.</div><div><br></div><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>variant&lt=
;void, empty&gt; v =3D foo(i);<br>v.visit([](empty) { std::cout &lt;&lt; &q=
uot;I&#39;m always &#39;empty&#39;&quot;; });<br></div></blockquote><div><b=
r></div><div>Why do you make such a claim? You&#39;ve explicitly stated tha=
t you can contain void here in the parameter list of variant, and so your v=
isitor should handle it in the visitation. It&#39;s nothing special. If you=
 didn&#39;t want to handle it, you simply wouldn&#39;t put it in the varian=
t. Just to keep things grounded with more practical examples, let&#39;s say=
 that your function &quot;foo&quot; is generic code living on a server and =
is reacting to a remote invocation request. It invokes &quot;f&quot; or it =
invokes &quot;g&quot; based on the information in the request (i.e. the fun=
ction name and serialized arguments) and it locally returns the result so t=
hat the calling-code can send a message back to the client. All that the ca=
ller of &quot;foo&quot; does with the result is visit it with a generic lam=
bda that serializes the result that is contained and sends it back to the c=
lient. If one of the functions happened to have a return type of void, then=
 so what? The serialization part of your visitation might be a null op, or =
it might contain type info, or anything at all, but it still sends back a m=
essage so that the client knows the call went through. Everything just work=
s because void is nothing special here, and there is nothing logically inco=
rrect with doing this in the visitor. You&#39;re just sending back a reply =
with the result -- it just so happens that the type may be one with no memb=
ers. If you arbitrarily special-case void for variant in such a way that it=
 corresponds to a lack of a member, rather than an empty member, then your =
visitation doesn&#39;t handle the void case and your client never receives =
the reply. This isn&#39;t some strange, contrived case and you will find th=
at this kind of thing comes up a lot when you are dealing with function res=
ults in generic code. This very scenario is strikingly similar to code I&#3=
9;ve written and is in use, and is not particularly unique. Right now, ther=
e is extra indirection to handle the void case, but it simply should not be=
 necessary when you think about the problem in the abstract. The same is tr=
ue for all generic code where you are dealing with a dependent type that ma=
y or may not be void and you need to pass along whatever state is there (wh=
ich may be state that contains nothing, such as void).=C2=A0</div><div><br>=
</div><div>If you don&#39;t buy into such explanations and real-world examp=
les, then exactly what code do you have in mind that benefits from the beha=
vior that you suggest? I understand that you&#39;re defining what you feel =
it should do, which seems to be different from any other type in the langua=
ge, and yet I see no practical rationale or real-world code to show why thi=
s would ever be desired. As far as I can see, it just prevents people from =
easily writing generic code and keeps people having to make strange workaro=
unds for void.</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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--089e0149c77a4b7603051c70a326--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Mon, 3 Aug 2015 16:41:55 -0700
Raw View
--001a113cd41afc8add051c70b6d2
Content-Type: text/plain; charset=UTF-8

On Mon, Aug 3, 2015 at 4:17 PM, Edward Catmur <ed@catmur.co.uk> wrote:
>
> For what it's worth, I think we have enough unit types in C++ already, and
> don't see why we need one more.


For the reasons expressed. This is genuinely important for generic code.
Dealing with void properly in generic code currently requires
specialization. This is true even in the standard library. Making void a
complete, regular type removes the need for special-casing and makes it
easier to write generic code.

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On M=
on, Aug 3, 2015 at 4:17 PM, Edward Catmur <span dir=3D"ltr">&lt;<a href=3D"=
mailto:ed@catmur.co.uk" target=3D"_blank">ed@catmur.co.uk</a>&gt;</span> wr=
ote:<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-lef=
t:1px #ccc solid;padding-left:1ex">
For what it&#39;s worth, I think we have enough unit types in C++ already, =
and don&#39;t see why we need one more.</blockquote><div><br></div><div>For=
 the reasons expressed. This is genuinely important for generic code. Deali=
ng with void properly in generic code currently requires specialization. Th=
is is true even in the standard library. Making void a complete, regular ty=
pe removes the need for special-casing and makes it easier to write generic=
 code.</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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a113cd41afc8add051c70b6d2--

.


Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Mon, 3 Aug 2015 19:55:10 -0700
Raw View
--f46d043892df14f9a2051c736a0e
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Mon, Aug 3, 2015 at 4:41 PM, 'Matt Calabrese' via ISO C++ Standard -
Future Proposals <std-proposals@isocpp.org> wrote:

> On Mon, Aug 3, 2015 at 4:17 PM, Edward Catmur <ed@catmur.co.uk> wrote:
>>
>> For what it's worth, I think we have enough unit types in C++ already,
>> and don't see why we need one more.
>
>
> For the reasons expressed. This is genuinely important for generic code.
> Dealing with void properly in generic code currently requires
> specialization. This is true even in the standard library. Making void a
> complete, regular type removes the need for special-casing and makes it
> easier to write generic code.
>

For the record, I do completely sympathize with Matt's point of view here.
C++'s special-case treatment of void *does* seem to me like a huge problem.
I just prefer to solve the problem in as conservative and incremental a
fashion as possible.

Our intuitions about what std::tuple<int,void> would mean, if it were
legal, are also 100% in agreement. That is, I disagree that it necessarily
*should* be legal, but if it *were* legal, I believe it would *have* to
have Matt's desired semantics.

Matt, what would you do about template type deduction in your system?

    template<typename T> void g(T) { }
    int main() {
        g();  // valid or invalid?
        g((void)0);  // valid or invalid?
    }

=E2=80=93Arthur

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

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

<div dir=3D"ltr">On Mon, Aug 3, 2015 at 4:41 PM, &#39;Matt Calabrese&#39; v=
ia ISO C++ Standard - Future Proposals <span dir=3D"ltr">&lt;<a href=3D"mai=
lto:std-proposals@isocpp.org" target=3D"_blank">std-proposals@isocpp.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:=
1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra=
"><div class=3D"gmail_quote"><span class=3D"">On Mon, Aug 3, 2015 at 4:17 P=
M, Edward Catmur <span dir=3D"ltr">&lt;<a href=3D"mailto:ed@catmur.co.uk" t=
arget=3D"_blank">ed@catmur.co.uk</a>&gt;</span> wrote:<blockquote class=3D"=
gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-=
left:1ex">
For what it&#39;s worth, I think we have enough unit types in C++ already, =
and don&#39;t see why we need one more.</blockquote><div><br></div></span><=
div>For the reasons expressed. This is genuinely important for generic code=
.. Dealing with void properly in generic code currently requires specializat=
ion. This is true even in the standard library. Making void a complete, reg=
ular type removes the need for special-casing and makes it easier to write =
generic code.</div></div></div></div></blockquote><div><br></div><div>For t=
he record, I do completely sympathize with Matt&#39;s point of view here. C=
++&#39;s special-case treatment of void=C2=A0<i>does</i> seem to me like a =
huge problem. I just prefer to solve the problem in as conservative and inc=
remental a fashion as possible.</div><div><br></div><div>Our intuitions abo=
ut what std::tuple&lt;int,void&gt; would mean, if it were legal, are also 1=
00% in agreement. That is, I disagree that it necessarily <i>should</i> be =
legal, but if it <i>were</i> legal, I believe it would <i>have</i> to have =
Matt&#39;s desired semantics.</div><div><br></div><div>Matt, what would you=
 do about template type deduction in your system?</div><div><br></div><div>=
=C2=A0 =C2=A0 template&lt;typename T&gt; void g(T) { }</div><div>=C2=A0 =C2=
=A0 int main() {</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 g(); =C2=A0// valid =
or invalid?</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 g((void)0); =C2=A0// vali=
d or invalid?</div><div>=C2=A0 =C2=A0 }</div><div><br></div><div>=E2=80=93A=
rthur</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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--f46d043892df14f9a2051c736a0e--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Mon, 3 Aug 2015 20:24:19 -0700
Raw View
--089e0122e6ba636c8e051c73d2a9
Content-Type: text/plain; charset=UTF-8

On Mon, Aug 3, 2015 at 7:55 PM, Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
wrote:

> Matt, what would you do about template type deduction in your system?
>
>     template<typename T> void g(T) { }
>     int main() {
>         g();  // valid or invalid?
>         g((void)0);  // valid or invalid?
>     }
>

It depends. The most conservative approach is to make g() invalid, and
g((void)0) valid, deducing T as void. The downside of this is that it means
that calling set_value() on something like a promise<void> would require an
explicit expression. What probably makes the most sense is to instead have
an empty argument be allowed as syntactic sugar for default-constructed
void. This allows easy use of unary void functions from both generic and
non-generic code. In other words, you'd be able to invoke
std::promise<void>'s set_value (which would now actually take const void&
or void&&), by just calling set_value() without passing in an explicit
argument. The subtlety here is if there is an overload that actually is
nullary. In such a case, the unary-void overload should be considered and
substitution should occur, but the nullary function would be considered a
better match during overload resolution:

//////////
using Void = void;

void foo() {}  // foo0
void foo(Void) {} // foo1

void bar() {} // bar0
template<class T>
void bar(T) {} // bar1

void baz(Void) {}

int main()
{
  foo(); // calls foo0
  foo(void()); // calls foo1

  bar(); // calls bar0
  bar(void()); // calls bar1, deducing T as void

  baz(); // calls baz
}
//////////

This is less conservative and a little more "risky," but would allow us to
remove the std::promise<void> specialization without breaking most
user-code (unless, or course, the user code was relying on the signature of
set_value, such as taking its address). Compiler-folks are probably best at
understanding the implications of allowing empty meaning
default-constructed-void obeying the rules specified above regarding
substitution and overload resolution.

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On M=
on, Aug 3, 2015 at 7:55 PM, Arthur O&#39;Dwyer <span dir=3D"ltr">&lt;<a hre=
f=3D"mailto:arthur.j.odwyer@gmail.com" target=3D"_blank">arthur.j.odwyer@gm=
ail.com</a>&gt;</span> wrote:<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"><div><div class=3D"h5"><span style=3D"color:rgb(34,34,34)">Matt, what=
 would you do about template type deduction in your system?</span><br></div=
></div><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div><br></div=
><div>=C2=A0 =C2=A0 template&lt;typename T&gt; void g(T) { }</div><div>=C2=
=A0 =C2=A0 int main() {</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 g(); =C2=A0//=
 valid or invalid?</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 g((void)0); =C2=A0=
// valid or invalid?</div><div>=C2=A0 =C2=A0 }</div></div></div></div></blo=
ckquote><div><br></div><div>It depends. The most conservative approach is t=
o make g() invalid, and g((void)0) valid, deducing T as void. The downside =
of this is that it means that calling set_value() on something like a promi=
se&lt;void&gt; would require an explicit expression. What probably makes th=
e most sense is to instead have an empty argument be allowed as syntactic s=
ugar for default-constructed void. This allows easy use of unary void funct=
ions from both generic and non-generic code. In other words, you&#39;d be a=
ble to invoke std::promise&lt;void&gt;&#39;s set_value (which would now act=
ually take const void&amp; or void&amp;&amp;), by just calling set_value() =
without passing in an explicit argument. The subtlety here is if there is a=
n overload that actually is nullary. In such a case, the unary-void overloa=
d should be considered and substitution should occur, but the nullary funct=
ion would be considered a better match during overload resolution:</div><di=
v><br></div><div>//////////</div><div>using Void =3D void;<br></div><div><b=
r></div><div>void foo() {} =C2=A0// foo0</div><div>void foo(Void) {} // foo=
1</div><div><br></div><div>void bar() {} // bar0</div><div>template&lt;clas=
s T&gt;</div><div>void bar(T) {} // bar1</div><div><br></div><div>void baz(=
Void) {}</div><div><br></div><div>int main()</div><div>{</div><div>=C2=A0 f=
oo(); // calls foo0</div><div>=C2=A0 foo(void()); // calls foo1</div><div><=
br></div><div>=C2=A0 bar(); // calls bar0</div><div>=C2=A0 bar(void()); // =
calls bar1, deducing T as void</div><div><br></div><div>=C2=A0 baz(); // ca=
lls baz</div><div>}</div><div>//////////</div><div><br></div><div>This is l=
ess conservative and a little more &quot;risky,&quot; but would allow us to=
 remove the std::promise&lt;void&gt; specialization without breaking most u=
ser-code (unless, or course, the user code was relying on the signature of =
set_value, such as taking its address). Compiler-folks are probably best at=
 understanding the implications of allowing empty meaning default-construct=
ed-void obeying the rules specified above regarding substitution and overlo=
ad resolution.</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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--089e0122e6ba636c8e051c73d2a9--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Mon, 3 Aug 2015 20:32:53 -0700
Raw View
--001a1142da9cfd2fd8051c73f084
Content-Type: text/plain; charset=UTF-8

On Mon, Aug 3, 2015 at 8:24 PM, Matt Calabrese <calabrese@google.com> wrote:
>
> This is less conservative and a little more "risky," but would allow us to
> remove the std::promise<void> specialization without breaking most
> user-code (unless, or course, the user code was relying on the signature of
> set_value, such as taking its address). Compiler-folks are probably best at
> understanding the implications of allowing empty meaning
> default-constructed-void obeying the rules specified above regarding
> substitution and overload resolution.
>

There is a also a more conservative approach that doesn't involve
specifying an empty argument to potentially be syntactic sugar for
default-constructed void: when removing the std::promise specialization for
void, give set_value a default-argument that is just default-constructed T.
This makes set_value easy to use without adding in the empty-argument
solution, but it means that set_value now also has a default argument. You
could use SFINAE to make it only default for void, but that's unfortunate
and would go back to the desire to special-case for void. Really it would
be great if it "just worked."

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On M=
on, Aug 3, 2015 at 8:24 PM, Matt Calabrese <span dir=3D"ltr">&lt;<a href=3D=
"mailto:calabrese@google.com" target=3D"_blank">calabrese@google.com</a>&gt=
;</span> wrote:<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 class=
=3D"gmail_extra"><div class=3D"gmail_quote"><div>This is less conservative =
and a little more &quot;risky,&quot; but would allow us to remove the std::=
promise&lt;void&gt; specialization without breaking most user-code (unless,=
 or course, the user code was relying on the signature of set_value, such a=
s taking its address). Compiler-folks are probably best at understanding th=
e implications of allowing empty meaning default-constructed-void obeying t=
he rules specified above regarding substitution and overload resolution.</d=
iv></div></div></div>
</blockquote></div><br></div><div class=3D"gmail_extra">There is a also a m=
ore conservative approach that doesn&#39;t involve specifying an empty argu=
ment to potentially be syntactic sugar for default-constructed void: when r=
emoving the std::promise specialization for void, give set_value a default-=
argument that is just default-constructed T. This makes set_value easy to u=
se without adding in the empty-argument solution, but it means that set_val=
ue now also has a default argument. You could use SFINAE to make it only de=
fault for void, but that&#39;s unfortunate and would go back to the desire =
to special-case for void. Really it would be great if it &quot;just worked.=
&quot;</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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a1142da9cfd2fd8051c73f084--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Mon, 3 Aug 2015 20:38:06 -0700
Raw View
--001a113cd41aa92fd5051c740331
Content-Type: text/plain; charset=UTF-8

On Mon, Aug 3, 2015 at 8:24 PM, Matt Calabrese <calabrese@google.com> wrote:

> On Mon, Aug 3, 2015 at 7:55 PM, Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
> wrote:
>
>> Matt, what would you do about template type deduction in your system?
>>
>>     template<typename T> void g(T) { }
>>     int main() {
>>         g();  // valid or invalid?
>>         g((void)0);  // valid or invalid?
>>     }
>>
>
> It depends. The most conservative approach is to make g() invalid, and
> g((void)0) valid, deducing T as void. The downside of this is that it means
> that calling set_value() on something like a promise<void> would require an
> explicit expression. What probably makes the most sense is to instead have
> an empty argument be allowed as syntactic sugar for default-constructed
> void. This allows easy use of unary void functions from both generic and
> non-generic code. In other words, you'd be able to invoke
> std::promise<void>'s set_value (which would now actually take const void&
> or void&&), by just calling set_value() without passing in an explicit
> argument. The subtlety here is if there is an overload that actually is
> nullary. In such a case, the unary-void overload should be considered and
> substitution should occur, but the nullary function would be considered a
> better match during overload resolution:]
>

Also, before being pointed out, yes, this has the potential to break code,
which is why it is the less conservative solution.

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On M=
on, Aug 3, 2015 at 8:24 PM, Matt Calabrese <span dir=3D"ltr">&lt;<a href=3D=
"mailto:calabrese@google.com" target=3D"_blank">calabrese@google.com</a>&gt=
;</span> wrote:<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"><div cla=
ss=3D"gmail_extra"><div class=3D"gmail_quote"><span class=3D"">On Mon, Aug =
3, 2015 at 7:55 PM, Arthur O&#39;Dwyer <span dir=3D"ltr">&lt;<a href=3D"mai=
lto:arthur.j.odwyer@gmail.com" target=3D"_blank">arthur.j.odwyer@gmail.com<=
/a>&gt;</span> wrote:<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"><d=
iv><div><span style=3D"color:rgb(34,34,34)">Matt, what would you do about t=
emplate type deduction in your system?</span><br></div></div><div class=3D"=
gmail_extra"><div class=3D"gmail_quote"><div><br></div><div>=C2=A0 =C2=A0 t=
emplate&lt;typename T&gt; void g(T) { }</div><div>=C2=A0 =C2=A0 int main() =
{</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 g(); =C2=A0// valid or invalid?</di=
v><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 g((void)0); =C2=A0// valid or invalid?</=
div><div>=C2=A0 =C2=A0 }</div></div></div></div></blockquote><div><br></div=
></span><div>It depends. The most conservative approach is to make g() inva=
lid, and g((void)0) valid, deducing T as void. The downside of this is that=
 it means that calling set_value() on something like a promise&lt;void&gt; =
would require an explicit expression. What probably makes the most sense is=
 to instead have an empty argument be allowed as syntactic sugar for defaul=
t-constructed void. This allows easy use of unary void functions from both =
generic and non-generic code. In other words, you&#39;d be able to invoke s=
td::promise&lt;void&gt;&#39;s set_value (which would now actually take cons=
t void&amp; or void&amp;&amp;), by just calling set_value() without passing=
 in an explicit argument. The subtlety here is if there is an overload that=
 actually is nullary. In such a case, the unary-void overload should be con=
sidered and substitution should occur, but the nullary function would be co=
nsidered a better match during overload resolution:]</div></div></div></div=
></blockquote><div><br></div><div>Also, before being pointed out, yes, this=
 has the potential to break code, which is why it is the less conservative =
solution.</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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a113cd41aa92fd5051c740331--

.


Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Mon, 3 Aug 2015 23:55:30 -0700
Raw View
--047d7b87390a98c2a4051c76c54d
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Mon, Aug 3, 2015 at 8:24 PM, 'Matt Calabrese' via ISO C++ Standard -
Future Proposals <std-proposals@isocpp.org> wrote:

> On Mon, Aug 3, 2015 at 7:55 PM, Arthur O'Dwyer <arthur.j.odwyer@gmail.com=
>
> wrote:
>
>> Matt, what would you do about template type deduction in your system?
>>
>>     template<typename T> void g(T) { }
>>     int main() {
>>         g();  // valid or invalid?
>>         g((void)0);  // valid or invalid?
>>     }
>>
>
> It depends. The most conservative approach is to make g() invalid, and
> g((void)0) valid, deducing T as void. The downside of this is that [it
> doesn't solve the problem we want to solve, namely
> std::promise<void>::set_value].
>

Notice that std::promise<void>::set_value(void) isn't exactly the same case
as what I'm talking about. In the set_value case, we merely need to allow a
parameter to have a type that is dependent yet void. C++ already allows
void types for non-dependently-typed parameters, so this should be
relatively simple. I'm talking about actually using type deduction to
*deduce* void for a parameter of *deduced* type.

However, even before we get there, I'm seeing repeatedly that you and I
disagree about the sensicality of a "unary function taking void".
In my world, that's impossible; a function whose argument list is
equivalent to void is nullary *by definition*.
And this is a good thing, because I *want* std::promise<void>::set_value() =
to
be a nullary function.

    using Void =3D void;
    // All three of these function signatures declare a nullary function.
    // IMO we *must* keep this working.
    void foo(Void);
    void foo(void);
    void foo();


using Void =3D void;
>
> void foo() {}  // foo0
> void foo(Void) {} // foo1
>

In my world this is a violation of the ODR; foo0 and foo1 are the same
function.


>
> void bar() {} // bar0
> template<class T>
> void bar(T) {} // bar1
>
> void baz(Void) {}
>
> int main()
> {
>   foo(); // calls foo0
>   foo(void()); // calls foo1
>
>   bar(); // calls bar0
>   bar(void()); // calls bar1, deducing T as void
>

The question I was asking in the previous message is: If bar0 was not
declared, would bar(); call bar1?


>   baz(); // calls baz
>

Of course; this has always been the case.

=E2=80=93Arthur

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

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

<div dir=3D"ltr">On Mon, Aug 3, 2015 at 8:24 PM, &#39;Matt Calabrese&#39; v=
ia ISO C++ Standard - Future Proposals <span dir=3D"ltr">&lt;<a href=3D"mai=
lto:std-proposals@isocpp.org" target=3D"_blank">std-proposals@isocpp.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:=
1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra=
"><div class=3D"gmail_quote"><span class=3D"">On Mon, Aug 3, 2015 at 7:55 P=
M, Arthur O&#39;Dwyer <span dir=3D"ltr">&lt;<a href=3D"mailto:arthur.j.odwy=
er@gmail.com" target=3D"_blank">arthur.j.odwyer@gmail.com</a>&gt;</span> wr=
ote:<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"><div><div><span sty=
le=3D"color:rgb(34,34,34)">Matt, what would you do about template type dedu=
ction in your system?</span><br></div></div><div class=3D"gmail_extra"><div=
 class=3D"gmail_quote"><div><br></div><div>=C2=A0 =C2=A0 template&lt;typena=
me T&gt; void g(T) { }</div><div>=C2=A0 =C2=A0 int main() {</div><div>=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 g(); =C2=A0// valid or invalid?</div><div>=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 g((void)0); =C2=A0// valid or invalid?</div><div>=C2=
=A0 =C2=A0 }</div></div></div></div></blockquote><div><br></div></span><div=
>It depends. The most conservative approach is to make g() invalid, and g((=
void)0) valid, deducing T as void. The downside of this is that [it doesn&#=
39;t solve the problem we want to solve, namely std::promise&lt;void&gt;::s=
et_value].</div></div></div></div></blockquote><div>=C2=A0</div><div>Notice=
 that std::promise&lt;void&gt;::set_value(void) isn&#39;t exactly the same =
case as what I&#39;m talking about. In the set_value case, we merely need t=
o allow a parameter to have a type that is dependent yet void. C++ already =
allows void types for non-dependently-typed parameters, so this should be r=
elatively simple. I&#39;m talking about actually using type deduction to <i=
>deduce</i> <font face=3D"monospace, monospace">void</font> for a parameter=
 of <i>deduced</i> type.</div><div><br></div><div>However, even before we g=
et there, I&#39;m seeing repeatedly that you and I disagree about the sensi=
cality of a &quot;unary function taking <font face=3D"monospace, monospace"=
>void</font>&quot;.</div><div>In my world, that&#39;s impossible; a functio=
n whose argument list is equivalent to <font face=3D"monospace, monospace">=
void</font> is nullary <i>by definition</i>.</div><div><div>And this is a g=
ood thing, because I=C2=A0<i>want</i>=C2=A0<font face=3D"monospace, monospa=
ce">std::promise&lt;void&gt;::set_value()</font>=C2=A0to be a nullary funct=
ion.</div></div><div><br></div><div><font face=3D"monospace, monospace">=C2=
=A0 =C2=A0 using Void =3D void;</font></div><div><font face=3D"monospace, m=
onospace">=C2=A0 =C2=A0 // All three of these function signatures declare a=
 nullary function.</font></div><div><font face=3D"monospace, monospace">=C2=
=A0 =C2=A0 // IMO we <b><i>must</i></b> keep this working.</font></div><div=
><font face=3D"monospace, monospace">=C2=A0 =C2=A0 void foo(Void);<br></fon=
t></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 void foo(voi=
d);</font></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 void=
 foo();</font></div><div><br></div><div><br></div><blockquote class=3D"gmai=
l_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left=
:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote=
"><div>using Void =3D void;<br></div><div><br></div><div>void foo() {} =C2=
=A0// foo0</div><div>void foo(Void) {} // foo1</div></div></div></div></blo=
ckquote><div><br></div><div>In my world this is a violation of the ODR; foo=
0 and foo1 are the same function.</div><div>=C2=A0<br></div><blockquote cla=
ss=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;pa=
dding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"g=
mail_quote"><div><br></div><div>void bar() {} // bar0</div><div>template&lt=
;class T&gt;</div><div>void bar(T) {} // bar1</div><div><br></div><div>void=
 baz(Void) {}</div><div><br></div><div>int main()</div><div>{</div><div>=C2=
=A0 foo(); // calls foo0</div><div>=C2=A0 foo(void()); // calls foo1</div><=
div><br></div><div>=C2=A0 bar(); // calls bar0</div><div>=C2=A0 bar(void())=
; // calls bar1, deducing T as void</div></div></div></div></blockquote><di=
v><br></div><div>The question I was asking in the previous message is: If b=
ar0 was not declared, would <font face=3D"monospace, monospace">bar();</fon=
t> call bar1?</div><div>=C2=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 class=3D"gmail_extra"><div class=3D"gmail_quote"><div>=C2=A0 =
baz(); // calls baz<br></div></div></div></div></blockquote><div><br></div>=
<div>Of course; this has always been the case.</div><div><br></div><div>=E2=
=80=93Arthur</div><div><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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--047d7b87390a98c2a4051c76c54d--

.


Author: Roland Bock <rbock@eudoxos.de>
Date: Tue, 04 Aug 2015 09:32:24 +0200
Raw View
This is a multi-part message in MIME format.
--------------080203060600010601030008
Content-Type: text/plain; charset=UTF-8

On 2015-08-04 08:55, Arthur O'Dwyer wrote:
>
>     using Void = void;
>
>     void foo() {}  // foo0
>     void foo(Void) {} // foo1
>
>
> In my world this is a violation of the ODR; foo0 and foo1 are the same
> function.
Being aware that this is currently the case I wonder if it is a good idea?

If we could have values of type void, then I doubt that the above makes
sense?

How about binary functions?

void foo0();              // zero parameters
void foo1(void);          // still zero parameters (you say)
void foo2(void, void);    // ???

and how about

void foo2(int, void);     // ???
void foo2(void, int);     // ???

I would prefer all of them to be different, foo0 having zero parameters,
foo1 having one parameters, foo2 having two parameters.


Seems to me that this ship has sailed though. There is simply too much
code depending on foo0 being the same as foo1, I guess :-(


We could however introduce a new thing, e.g. std::none, that could be
designed from afresh and have all the nice features we would like to see
in void.

Regards,

Roland




--

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

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

<html>
  <head>
    <meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Type=
">
  </head>
  <body bgcolor=3D"#FFFFFF" text=3D"#000000">
    <div class=3D"moz-cite-prefix">On 2015-08-04 08:55, Arthur O'Dwyer
      wrote:<br>
    </div>
    <blockquote
cite=3D"mid:CADvuK0J43fEVs+Za3_FDe21i-RChA6uCEaEtbqg9UmOcWWk-HA@mail.gmail.=
com"
      type=3D"cite">
      <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 class=3D"gmail_extra">
            <div class=3D"gmail_quote">
              <div>using Void =3D void;<br>
              </div>
              <div><br>
              </div>
              <div>void foo() {} =C2=A0// foo0</div>
              <div>void foo(Void) {} // foo1</div>
            </div>
          </div>
        </div>
      </blockquote>
      <div><br>
      </div>
      <div>In my world this is a violation of the ODR; foo0 and foo1 are
        the same function.</div>
    </blockquote>
    Being aware that this is currently the case I wonder if it is a good
    idea?<br>
    <br>
    If we could have values of type void, then I doubt that the above
    makes sense?<br>
    <br>
    How about binary functions?<br>
    <br>
    <tt>void foo0();=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0 // zero parameters</tt><tt><br>
    </tt><tt>void foo1(void);=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 // still zero parameters (you
      say)</tt><tt><br>
    </tt><tt>void foo2(void, void);=C2=A0=C2=A0=C2=A0 // ???</tt><tt><br>
    </tt><br>
    and how about <br>
    <br>
    <tt>void foo2(int, void);=C2=A0=C2=A0=C2=A0=C2=A0 // ???</tt><tt><br>
    </tt><tt>void foo2(void, int);=C2=A0=C2=A0=C2=A0=C2=A0 // ???</tt><br>
    <br>
    I would prefer all of them to be different, foo0 having zero
    parameters, foo1 having one parameters, foo2 having two parameters.<br>
    <br>
    <br>
    Seems to me that this ship has sailed though. There is simply too
    much code depending on foo0 being the same as foo1, I guess :-(<br>
    <br>
    <br>
    We could however introduce a new thing, e.g. std::none, that could
    be designed from afresh and have all the nice features we would like
    to see in void.<br>
    <br>
    Regards,<br>
    <br>
    Roland<br>
    <br>
    <br>
    <br>
    <br>
  </body>
</html>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--------------080203060600010601030008--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Tue, 4 Aug 2015 00:44:21 -0700
Raw View
--089e01634d7e52f763051c777418
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Mon, Aug 3, 2015 at 11:55 PM, Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
wrote:
>
> Notice that std::promise<void>::set_value(void) isn't exactly the same
> case as what I'm talking about. In the set_value case, we merely need to
> allow a parameter to have a type that is dependent yet void. C++ already
> allows void types for non-dependently-typed parameters, so this should be
> relatively simple. I'm talking about actually using type deduction to
> *deduce* void for a parameter of *deduced* type.
>

I know the case you are talking about -- I already explained how it'd be
handled, I'm just trying to show all cases for clarity and to show its
consistency with the non-deduced version. I don't believe that we should
change one without changing the other. Ideally they are consistent with one
another.

However, even before we get there, I'm seeing repeatedly that you and I
> disagree about the sensicality of a "unary function taking void".
> In my world, that's impossible; a function whose argument list is
> equivalent to void is nullary *by definition*.
>

Then you are being inconsistent in what you think void means. You've
already stated that you understand what tuple<int, void> is and it is
consistent with what I've stated. This effectively implies that you accept
unary void is a sensible construct. To be clear on why that is, simply
imagine a make_tuple-like facility that takes the arguments by value. What
do you think the signature of that function is for a tuple<int, int>? What
do you think the signature is for tuple<int, void, int>? What about
tuple<void>? What about tuple<>? Note that the last two cases are
*very* different.
The former is a unary function that takes void. The latter is a true,
nullary function. They are in no way the same thing. Do not flatten unary
void to nullary. They are distinct.


> And this is a good thing, because I *want* std::promise<void>::set_value(=
) to
> be a nullary function.
>
>     using Void =3D void;
>     // All three of these function signatures declare a nullary function.
>     // IMO we *must* keep this working.
>     void foo(Void);
>     void foo(void);
>     void foo();
>

My mistake -- I was thinking that declarations using a typedef of void were
currently illegal, but that is only the case if the typedef was dependent.
I agree that this particular syntax shouldn't change meaning, then.
However, regardless of what the syntax is in the non-dependent context,
there still needs to be a way to declare such a function. However it is to
be declared, the behavior shown is what we should expect. It's just less
than ideal that we can't use the natural syntax for it in the unary case (a
function taking a single void parameter). When the type is dependent, which
is the case we are trying to fix for generic code, this would work directly=
..

The question I was asking in the previous message is: If bar0 was not
> declared, would bar(); call bar1?
>

Yes, as I described, that overload would be considered and go through
substitution. The nullary version is only picked because it is a better
match. If the nullary version weren't there, then bar1 would be picked.

>
>
>>   baz(); // calls baz
>>
>
> Of course; this has always been the case.
>

Again, I'm just enumerating the relevant cases. Pretend this is the
hypothetical unary void case (as opposed to the nullary case), however it
would actually be declared.

On Mon, Aug 3, 2015 at 11:55 PM, Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
wrote:

> On Mon, Aug 3, 2015 at 8:24 PM, 'Matt Calabrese' via ISO C++ Standard -
> Future Proposals <std-proposals@isocpp.org> wrote:
>
>> On Mon, Aug 3, 2015 at 7:55 PM, Arthur O'Dwyer <arthur.j.odwyer@gmail.co=
m
>> > wrote:
>>
>>> Matt, what would you do about template type deduction in your system?
>>>
>>>     template<typename T> void g(T) { }
>>>     int main() {
>>>         g();  // valid or invalid?
>>>         g((void)0);  // valid or invalid?
>>>     }
>>>
>>
>> It depends. The most conservative approach is to make g() invalid, and
>> g((void)0) valid, deducing T as void. The downside of this is that [it
>> doesn't solve the problem we want to solve, namely
>> std::promise<void>::set_value].
>>
>
> Notice that std::promise<void>::set_value(void) isn't exactly the same
> case as what I'm talking about. In the set_value case, we merely need to
> allow a parameter to have a type that is dependent yet void. C++ already
> allows void types for non-dependently-typed parameters, so this should be
> relatively simple. I'm talking about actually using type deduction to
> *deduce* void for a parameter of *deduced* type.
>
> However, even before we get there, I'm seeing repeatedly that you and I
> disagree about the sensicality of a "unary function taking void".
> In my world, that's impossible; a function whose argument list is
> equivalent to void is nullary *by definition*.
> And this is a good thing, because I *want* std::promise<void>::set_value(=
) to
> be a nullary function.
>
>     using Void =3D void;
>     // All three of these function signatures declare a nullary function.
>     // IMO we *must* keep this working.
>     void foo(Void);
>     void foo(void);
>     void foo();
>
>
> using Void =3D void;
>>
>> void foo() {}  // foo0
>> void foo(Void) {} // foo1
>>
>
> In my world this is a violation of the ODR; foo0 and foo1 are the same
> function.
>
>
>>
>> void bar() {} // bar0
>> template<class T>
>> void bar(T) {} // bar1
>>
>> void baz(Void) {}
>>
>> int main()
>> {
>>   foo(); // calls foo0
>>   foo(void()); // calls foo1
>>
>>   bar(); // calls bar0
>>   bar(void()); // calls bar1, deducing T as void
>>
>
> The question I was asking in the previous message is: If bar0 was not
> declared, would bar(); call bar1?
>
>
>>   baz(); // calls baz
>>
>
> Of course; this has always been the case.
>
> =E2=80=93Arthur
>
> --
>
> ---
> 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/.

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><br><div class=3D"gmail_quote">=
On Mon, Aug 3, 2015 at 11:55 PM, Arthur O&#39;Dwyer <span dir=3D"ltr">&lt;<=
a href=3D"mailto:arthur.j.odwyer@gmail.com" target=3D"_blank">arthur.j.odwy=
er@gmail.com</a>&gt;</span> wrote:=C2=A0<blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div=
 dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div>Not=
ice that std::promise&lt;void&gt;::set_value(void) isn&#39;t exactly the sa=
me case as what I&#39;m talking about. In the set_value case, we merely nee=
d to allow a parameter to have a type that is dependent yet void. C++ alrea=
dy allows void types for non-dependently-typed parameters, so this should b=
e relatively simple. I&#39;m talking about actually using type deduction to=
 <i>deduce</i> <font face=3D"monospace, monospace">void</font> for a parame=
ter of <i>deduced</i> type.</div></div></div></div></blockquote><div><br></=
div><div>I know the case you are talking about -- I already explained how i=
t&#39;d be handled, I&#39;m just trying to show all cases for clarity and t=
o show its consistency with the non-deduced version. I don&#39;t believe th=
at we should change one without changing the other. Ideally they are consis=
tent with one another.</div><div><br></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 class=3D"gmail_extra"><div class=3D"gmail_quote"><div>=
However, even before we get there, I&#39;m seeing repeatedly that you and I=
 disagree about the sensicality of a &quot;unary function taking <font face=
=3D"monospace, monospace">void</font>&quot;.<br></div><div>In my world, tha=
t&#39;s impossible; a function whose argument list is equivalent to <font f=
ace=3D"monospace, monospace">void</font> is nullary <i>by definition</i>.</=
div></div></div></div></blockquote><div><br></div><div>Then you are being i=
nconsistent in what you think void means. You&#39;ve already stated that yo=
u understand what tuple&lt;int, void&gt; is and it is consistent with what =
I&#39;ve stated. This effectively implies that you accept unary void is a s=
ensible construct. To be clear on why that is, simply imagine a make_tuple-=
like facility that takes the arguments by value. What do you think the sign=
ature of that function is for a tuple&lt;int, int&gt;? What do you think th=
e signature is for tuple&lt;int, void, int&gt;? What about tuple&lt;void&gt=
;? What about tuple&lt;&gt;? Note that the last two cases are <i>very</i>=
=C2=A0different. The former is a unary function that takes void. The latter=
 is a true, nullary function. They are in no way the same thing. Do not fla=
tten unary void to nullary. They are distinct.</div><div>=C2=A0</div><block=
quote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc=
 solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><div c=
lass=3D"gmail_quote"><div><div>And this is a good thing, because I=C2=A0<i>=
want</i>=C2=A0<font face=3D"monospace, monospace">std::promise&lt;void&gt;:=
:set_value()</font>=C2=A0to be a nullary function.</div></div><div><br></di=
v><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 using Void =3D voi=
d;</font></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 // Al=
l three of these function signatures declare a nullary function.</font></di=
v><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 // IMO we <b><i>mu=
st</i></b> keep this working.</font></div><div><font face=3D"monospace, mon=
ospace">=C2=A0 =C2=A0 void foo(Void);<br></font></div><div><font face=3D"mo=
nospace, monospace">=C2=A0 =C2=A0 void foo(void);</font></div><div><font fa=
ce=3D"monospace, monospace">=C2=A0 =C2=A0 void foo();</font></div></div></d=
iv></div></blockquote><div><br></div><div>My mistake -- I was thinking that=
 declarations using a typedef of void were currently illegal, but that is o=
nly the case if the typedef was dependent. I agree that this particular syn=
tax shouldn&#39;t change meaning, then. However, regardless of what the syn=
tax is in the non-dependent context, there still needs to be a way to decla=
re such a function. However it is to be declared, the behavior shown is wha=
t we should expect. It&#39;s just less than ideal that we can&#39;t use the=
 natural syntax for it in the unary case (a function taking a single void p=
arameter). When the type is dependent, which is the case we are trying to f=
ix for generic code, this would work directly.</div><div><br></div><blockqu=
ote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><div cla=
ss=3D"gmail_quote"><div>The question I was asking in the previous message i=
s: If bar0 was not declared, would <font face=3D"monospace, monospace">bar(=
);</font> call bar1?</div></div></div></div></blockquote><div><br></div><di=
v>Yes, as I described, that overload would be considered and go through sub=
stitution. The nullary version is only picked because it is a better match.=
 If the nullary version weren&#39;t there, then bar1 would be picked.</div>=
<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 class=3D"gmail_extra">=
<div class=3D"gmail_quote"><div>=C2=A0</div><blockquote class=3D"gmail_quot=
e" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">=
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div=
>=C2=A0 baz(); // calls baz<br></div></div></div></div></blockquote><div><b=
r></div><div>Of course; this has always been the case.</div></div></div></d=
iv></blockquote><div><br></div><div>Again, I&#39;m just enumerating the rel=
evant cases. Pretend this is the hypothetical unary void case (as opposed t=
o the nullary case), however it would actually be declared.</div></div></di=
v></div><div class=3D"gmail_extra"><br><div class=3D"gmail_quote">On Mon, A=
ug 3, 2015 at 11:55 PM, Arthur O&#39;Dwyer <span dir=3D"ltr">&lt;<a href=3D=
"mailto:arthur.j.odwyer@gmail.com" target=3D"_blank">arthur.j.odwyer@gmail.=
com</a>&gt;</span> wrote:<br><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=
"><span class=3D"">On Mon, Aug 3, 2015 at 8:24 PM, &#39;Matt Calabrese&#39;=
 via ISO C++ Standard - Future Proposals <span dir=3D"ltr">&lt;<a href=3D"m=
ailto:std-proposals@isocpp.org" target=3D"_blank">std-proposals@isocpp.org<=
/a>&gt;</span> wrote:<br></span><div class=3D"gmail_extra"><div class=3D"gm=
ail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bor=
der-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gm=
ail_extra"><div class=3D"gmail_quote"><span class=3D""><span>On Mon, Aug 3,=
 2015 at 7:55 PM, Arthur O&#39;Dwyer <span dir=3D"ltr">&lt;<a href=3D"mailt=
o:arthur.j.odwyer@gmail.com" target=3D"_blank">arthur.j.odwyer@gmail.com</a=
>&gt;</span> wrote:<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"><div=
><div><span style=3D"color:rgb(34,34,34)">Matt, what would you do about tem=
plate type deduction in your system?</span><br></div></div><div class=3D"gm=
ail_extra"><div class=3D"gmail_quote"><div><br></div><div>=C2=A0 =C2=A0 tem=
plate&lt;typename T&gt; void g(T) { }</div><div>=C2=A0 =C2=A0 int main() {<=
/div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 g(); =C2=A0// valid or invalid?</div>=
<div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 g((void)0); =C2=A0// valid or invalid?</di=
v><div>=C2=A0 =C2=A0 }</div></div></div></div></blockquote><div><br></div><=
/span></span><div>It depends. The most conservative approach is to make g()=
 invalid, and g((void)0) valid, deducing T as void. The downside of this is=
 that [it doesn&#39;t solve the problem we want to solve, namely std::promi=
se&lt;void&gt;::set_value].</div></div></div></div></blockquote><div>=C2=A0=
</div><div>Notice that std::promise&lt;void&gt;::set_value(void) isn&#39;t =
exactly the same case as what I&#39;m talking about. In the set_value case,=
 we merely need to allow a parameter to have a type that is dependent yet v=
oid. C++ already allows void types for non-dependently-typed parameters, so=
 this should be relatively simple. I&#39;m talking about actually using typ=
e deduction to <i>deduce</i> <font face=3D"monospace, monospace">void</font=
> for a parameter of <i>deduced</i> type.</div><div><br></div><div>However,=
 even before we get there, I&#39;m seeing repeatedly that you and I disagre=
e about the sensicality of a &quot;unary function taking <font face=3D"mono=
space, monospace">void</font>&quot;.</div><div>In my world, that&#39;s impo=
ssible; a function whose argument list is equivalent to <font face=3D"monos=
pace, monospace">void</font> is nullary <i>by definition</i>.</div><div><di=
v>And this is a good thing, because I=C2=A0<i>want</i>=C2=A0<font face=3D"m=
onospace, monospace">std::promise&lt;void&gt;::set_value()</font>=C2=A0to b=
e a nullary function.</div></div><div><br></div><div><font face=3D"monospac=
e, monospace">=C2=A0 =C2=A0 using Void =3D void;</font></div><div><font fac=
e=3D"monospace, monospace">=C2=A0 =C2=A0 // All three of these function sig=
natures declare a nullary function.</font></div><div><font face=3D"monospac=
e, monospace">=C2=A0 =C2=A0 // IMO we <b><i>must</i></b> keep this working.=
</font></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 void fo=
o(Void);<br></font></div><div><font face=3D"monospace, monospace">=C2=A0 =
=C2=A0 void foo(void);</font></div><div><font face=3D"monospace, monospace"=
>=C2=A0 =C2=A0 void foo();</font></div><span class=3D""><div><br></div><div=
><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bor=
der-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gm=
ail_extra"><div class=3D"gmail_quote"><div>using Void =3D void;<br></div><d=
iv><br></div><div>void foo() {} =C2=A0// foo0</div><div>void foo(Void) {} /=
/ foo1</div></div></div></div></blockquote><div><br></div></span><div>In my=
 world this is a violation of the ODR; foo0 and foo1 are the same function.=
</div><span class=3D""><div>=C2=A0<br></div><blockquote class=3D"gmail_quot=
e" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">=
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div=
><br></div><div>void bar() {} // bar0</div><div>template&lt;class T&gt;</di=
v><div>void bar(T) {} // bar1</div><div><br></div><div>void baz(Void) {}</d=
iv><div><br></div><div>int main()</div><div>{</div><div>=C2=A0 foo(); // ca=
lls foo0</div><div>=C2=A0 foo(void()); // calls foo1</div><div><br></div><d=
iv>=C2=A0 bar(); // calls bar0</div><div>=C2=A0 bar(void()); // calls bar1,=
 deducing T as void</div></div></div></div></blockquote><div><br></div></sp=
an><div>The question I was asking in the previous message is: If bar0 was n=
ot declared, would <font face=3D"monospace, monospace">bar();</font> call b=
ar1?</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margi=
n:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">=
<div class=3D"gmail_extra"><div class=3D"gmail_quote"><div>=C2=A0 baz(); //=
 calls baz<br></div></div></div></div></blockquote><div><br></div><div>Of c=
ourse; this has always been the case.</div><span class=3D"HOEnZb"><font col=
or=3D"#888888"><div><br></div><div>=E2=80=93Arthur</div><div><br></div></fo=
nt></span></div></div></div><div class=3D"HOEnZb"><div class=3D"h5">

<p></p>

-- <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+unsubscribe@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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--089e01634d7e52f763051c777418--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Tue, 4 Aug 2015 01:02:32 -0700
Raw View
--089e01634d7e5d21b7051c77b5fc
Content-Type: text/plain; charset=UTF-8

On Tue, Aug 4, 2015 at 12:32 AM, Roland Bock <rbock@eudoxos.de> wrote:
>
>
> How about binary functions?
>
> void foo0();              // zero parameters
> void foo1(void);          // still zero parameters (you say)
> void foo2(void, void);    // ???
>
> and how about
>
> void foo2(int, void);     // ???
> void foo2(void, int);     // ???
>
> I would prefer all of them to be different, foo0 having zero parameters,
> foo1 having one parameters, foo2 having two parameters.
>

Yes!!! They are all logically different, we realistically just can't use
the syntax for foo1.

We could however introduce a new thing, e.g. std::none, that could be
> designed from afresh and have all the nice features we would like to see in
> void
>

Unfortunately that wouldn't help generic code unless everyone just updated
all of their code over night and nobody instantiated templates with void,
which realistically wouldn't happen. void is going to stay so ideally we
actually fix it in some way. IMO, we're really close to getting there. The
only thing we don't have IMHO is a good syntax for representing a unary
void function when void is not dependent. It's fine if there is an odd-ball
syntax for it because the dependent case is the one that comes up in
generic code. You wouldn't need to use the weird syntax there.

One possible solution -- we could have unary void functions declared as:

/////
void foo(explicit void) {}
/////

This is syntax that was illegal before, introduces no new keywords or
types, and doesn't look too obscure. There are probably many alternatives
and I'm not saying this is what it should be, we'd just need to pick one
that makes the most sense.

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
ue, Aug 4, 2015 at 12:32 AM, Roland Bock <span dir=3D"ltr">&lt;<a href=3D"m=
ailto:rbock@eudoxos.de" target=3D"_blank">rbock@eudoxos.de</a>&gt;</span> w=
rote:<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-le=
ft:1px #ccc solid;padding-left:1ex"><div bgcolor=3D"#FFFFFF" text=3D"#00000=
0">
    <br>
    How about binary functions?<br>
    <br>
    <tt>void foo0();=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0 // zero parameters</tt><tt><br>
    </tt><tt>void foo1(void);=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 // still zero parameters (you
      say)</tt><tt><br>
    </tt><tt>void foo2(void, void);=C2=A0=C2=A0=C2=A0 // ???</tt><tt><br>
    </tt><br>
    and how about <br>
    <br>
    <tt>void foo2(int, void);=C2=A0=C2=A0=C2=A0=C2=A0 // ???</tt><tt><br>
    </tt><tt>void foo2(void, int);=C2=A0=C2=A0=C2=A0=C2=A0 // ???</tt><br>
    <br>
    I would prefer all of them to be different, foo0 having zero
    parameters, foo1 having one parameters, foo2 having two parameters.<br>=
</div></blockquote><div><br></div><div>Yes!!! They are all logically differ=
ent, we realistically just can&#39;t use the syntax for foo1.</div><div><br=
></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-=
left:1px #ccc solid;padding-left:1ex"><div bgcolor=3D"#FFFFFF" text=3D"#000=
000">We could however introduce a new thing, e.g. std::none, that could
    be designed from afresh and have all the nice features we would like
    to see in void<br></div></blockquote><div><br></div><div>Unfortunately =
that wouldn&#39;t help generic code unless everyone just updated all of the=
ir code over night and nobody instantiated templates with void, which reali=
stically wouldn&#39;t happen. void is going to stay so ideally we actually =
fix it in some way. IMO, we&#39;re really close to getting there. The only =
thing we don&#39;t have IMHO is a good syntax for representing a unary void=
 function when void is not dependent. It&#39;s fine if there is an odd-ball=
 syntax for it because the dependent case is the one that comes up in gener=
ic code. You wouldn&#39;t need to use the weird syntax there.</div><div><br=
></div><div>One possible solution -- we could have unary void functions dec=
lared as:</div><div><br></div><div>/////</div><div>void foo(explicit void) =
{}</div><div>/////</div><div><br></div><div>This is syntax that was illegal=
 before, introduces no new keywords or types, and doesn&#39;t look too obsc=
ure. There are probably many alternatives and I&#39;m not saying this is wh=
at it should be, we&#39;d just need to pick one that makes the most sense.=
=C2=A0</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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--089e01634d7e5d21b7051c77b5fc--

.


Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Tue, 4 Aug 2015 01:05:30 -0700
Raw View
--047d7bb04906f6379c051c77bff0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Tue, Aug 4, 2015 at 12:32 AM, Roland Bock <rbock@eudoxos.de> wrote:

> On 2015-08-04 08:55, Arthur O'Dwyer wrote:
>
> using Void =3D void;
>>
>> void foo() {}  // foo0
>> void foo(Void) {} // foo1
>>
>
> In my world this is a violation of the ODR; foo0 and foo1 are the same
> function.
>
> Being aware that this is currently the case I wonder if it is a good idea=
?
>
> If we could have values of type void, then I doubt that the above makes
> sense?
>
[...]

> We could however introduce a new thing, e.g. std::none, that could be
> designed from afresh and have all the nice features we would like to see =
in
> void.
>

Sounds like std::nullptr_t is already *that* thing: it's new, it's unitary,
it provides relational operators. If you just want something that behaves
like Python's None, nullptr fits the bill exactly.

Another new-in-C++11, unitary, regular type in the standard library is
std::tuple<> (that is, a tuple of zero elements).

But the problem is generic programming that needs to work with void
parameter types (a.k.a. nullary functions) and void return types =E2=80=94 =
not
nullptr_t, not std::tuple<>, but literally and exactly void. Inventing new
types almost certainly won't solve the problem, because the problem
specifically concerns void.

=E2=80=93Arthur

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

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

<div dir=3D"ltr">On Tue, Aug 4, 2015 at 12:32 AM, Roland Bock <span dir=3D"=
ltr">&lt;<a href=3D"mailto:rbock@eudoxos.de" target=3D"_blank">rbock@eudoxo=
s.de</a>&gt;</span> wrote:<br><div class=3D"gmail_extra"><div class=3D"gmai=
l_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;borde=
r-left:1px #ccc solid;padding-left:1ex">
 =20
   =20
 =20
  <div bgcolor=3D"#FFFFFF" text=3D"#000000"><span class=3D"">
    <div>On 2015-08-04 08:55, Arthur O&#39;Dwyer
      wrote:<br>
    </div>
    <blockquote type=3D"cite">
      <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 class=3D"gmail_extra">
            <div class=3D"gmail_quote">
              <div>using Void =3D void;<br>
              </div>
              <div><br>
              </div>
              <div>void foo() {} =C2=A0// foo0</div>
              <div>void foo(Void) {} // foo1</div>
            </div>
          </div>
        </div>
      </blockquote>
      <div><br>
      </div>
      <div>In my world this is a violation of the ODR; foo0 and foo1 are
        the same function.</div>
    </blockquote></span>
    Being aware that this is currently the case I wonder if it is a good
    idea?<br>
    <br>
    If we could have values of type void, then I doubt that the above
    makes sense?<br></div></blockquote><div>[...]=C2=A0</div><blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;p=
adding-left:1ex"><div bgcolor=3D"#FFFFFF" text=3D"#000000">We could however=
 introduce a new thing, e.g. std::none, that could
    be designed from afresh and have all the nice features we would like
    to see in void.<br></div></blockquote><div><br></div><div>Sounds like <=
font face=3D"monospace, monospace">std::nullptr_t</font> is already <i>that=
</i> thing: it&#39;s new, it&#39;s unitary, it provides relational operator=
s. If you just want something that behaves like Python&#39;s <font face=3D"=
monospace, monospace">None</font>, nullptr fits the bill exactly.</div><div=
><br></div><div>Another new-in-C++11, unitary, regular type in the standard=
 library is <font face=3D"monospace, monospace">std::tuple&lt;&gt;</font> (=
that is, a tuple of zero elements).</div><div><br></div><div>But the proble=
m is generic programming that needs to work with void parameter types (a.k.=
a. nullary functions) and void return types =E2=80=94 not <font face=3D"mon=
ospace, monospace">nullptr_t</font>, not <font face=3D"monospace, monospace=
">std::tuple&lt;&gt;</font>, but literally and exactly=C2=A0<font face=3D"m=
onospace, monospace">void</font>. Inventing new types almost certainly won&=
#39;t solve the problem, because the problem specifically concerns=C2=A0<fo=
nt face=3D"monospace, monospace">void</font>.</div><div><br></div><div>=E2=
=80=93Arthur</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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--047d7bb04906f6379c051c77bff0--

.


Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Tue, 4 Aug 2015 01:25:29 -0700
Raw View
--f46d0438940f710f8e051c78075a
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Tue, Aug 4, 2015 at 12:44 AM, 'Matt Calabrese' via ISO C++ Standard -
Future Proposals <std-proposals@isocpp.org> wrote:

>
> On Mon, Aug 3, 2015 at 11:55 PM, Arthur O'Dwyer <arthur.j.odwyer@gmail.co=
m
> > wrote:
>>
>> Notice that std::promise<void>::set_value(void) isn't exactly the same
>> case as what I'm talking about. In the set_value case, we merely need to
>> allow a parameter to have a type that is dependent yet void. C++ already
>> allows void types for non-dependently-typed parameters, so this should b=
e
>> relatively simple. I'm talking about actually using type deduction to
>> *deduce* void for a parameter of *deduced* type.
>>
>
> I know the case you are talking about -- I already explained how it'd be
> handled, I'm just trying to show all cases for clarity and to show its
> consistency with the non-deduced version. I don't believe that we should
> change one without changing the other. Ideally they are consistent with o=
ne
> another.
>
> However, even before we get there, I'm seeing repeatedly that you and I
>> disagree about the sensicality of a "unary function taking void".
>> In my world, that's impossible; a function whose argument list is
>> equivalent to void is nullary *by definition*.
>>
>
> Then you are being inconsistent in what you think void means. You've
> already stated that you understand what tuple<int, void> is and it is
> consistent with what I've stated. This effectively implies that you accep=
t
> unary void is a sensible construct.
>

Not really. It means I see what you mean by tuple<int,void> =E2=80=94 you m=
ean an
object t such that std::tuple_size(t) returns 2, std::get<0>(t) returns an
int and std::get<1>(t) returns nothing. That much isn't controversial to me=
..
I understand that you want to be able to construct such an object via
std::make_tuple(1,
void()). I consider *that* part controversial.



> To be clear on why that is, simply imagine a make_tuple-like facility tha=
t
> takes the arguments by value. What do you think the signature of that
> function is for a tuple<int, int>? What do you think the signature is for
> tuple<int, void, int>? What about tuple<void>? What about tuple<>? Note
> that the last two cases are *very* different. The former is a unary
> function that takes void. The latter is a true, nullary function. They ar=
e
> in no way the same thing. Do not flatten unary void to nullary. They are
> distinct.
>

I agree that std::tuple<void>, if it were allowed, would be a different
type from std::tuple<>, in exactly the same way that boost::mpl::list<void>
is a different type from boost::mpl::list<>.
However, int(*)(void) and int(*)() denote the same type; always have,
always will, and IMO always should.
I don't know how to reconcile std::tuple<void> with make_tuple. I don't
think that introducing a new "unary void" is the right way to do it.
Instead of introducing "unary void", I would rather leave std::tuple<void>
ill-formed, or even say that it is well-formed but that instances of it
cannot be constructed via any kind of make_tuple.

=E2=80=93Arthur

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

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

<div dir=3D"ltr">On Tue, Aug 4, 2015 at 12:44 AM, &#39;Matt Calabrese&#39; =
via ISO C++ Standard - Future Proposals <span dir=3D"ltr">&lt;<a href=3D"ma=
ilto:std-proposals@isocpp.org" target=3D"_blank">std-proposals@isocpp.org</=
a>&gt;</span> wrote:<br><div class=3D"gmail_extra"><div class=3D"gmail_quot=
e"><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 class=3D"gmail_extr=
a"><br><div class=3D"gmail_quote"><span class=3D"">On Mon, Aug 3, 2015 at 1=
1:55 PM, Arthur O&#39;Dwyer <span dir=3D"ltr">&lt;<a href=3D"mailto:arthur.=
j.odwyer@gmail.com" target=3D"_blank">arthur.j.odwyer@gmail.com</a>&gt;</sp=
an> wrote:=C2=A0<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8e=
x;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=
=3D"gmail_extra"><div class=3D"gmail_quote"><div>Notice that std::promise&l=
t;void&gt;::set_value(void) isn&#39;t exactly the same case as what I&#39;m=
 talking about. In the set_value case, we merely need to allow a parameter =
to have a type that is dependent yet void. C++ already allows void types fo=
r non-dependently-typed parameters, so this should be relatively simple. I&=
#39;m talking about actually using type deduction to <i>deduce</i> <font fa=
ce=3D"monospace, monospace">void</font> for a parameter of <i>deduced</i> t=
ype.</div></div></div></div></blockquote><div><br></div></span><div>I know =
the case you are talking about -- I already explained how it&#39;d be handl=
ed, I&#39;m just trying to show all cases for clarity and to show its consi=
stency with the non-deduced version. I don&#39;t believe that we should cha=
nge one without changing the other. Ideally they are consistent with one an=
other.</div><span class=3D""><div><br></div><blockquote class=3D"gmail_quot=
e" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">=
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div=
>However, even before we get there, I&#39;m seeing repeatedly that you and =
I disagree about the sensicality of a &quot;unary function taking <font fac=
e=3D"monospace, monospace">void</font>&quot;.<br></div><div>In my world, th=
at&#39;s impossible; a function whose argument list is equivalent to <font =
face=3D"monospace, monospace">void</font> is nullary <i>by definition</i>.<=
/div></div></div></div></blockquote><div><br></div></span><div>Then you are=
 being inconsistent in what you think void means. You&#39;ve already stated=
 that you understand what tuple&lt;int, void&gt; is and it is consistent wi=
th what I&#39;ve stated. This effectively implies that you accept unary voi=
d is a sensible construct.</div></div></div></div></blockquote><div><br></d=
iv><div>Not really. It means I see what you mean by<font face=3D"monospace,=
 monospace"> tuple&lt;int,void&gt;</font> =E2=80=94 you mean an object <fon=
t face=3D"monospace, monospace">t</font> such that <font face=3D"monospace,=
 monospace">std::tuple_size(t)</font> returns <font face=3D"monospace, mono=
space">2</font>,=C2=A0<font face=3D"monospace, monospace">std::get&lt;0&gt;=
(t)</font> returns an int and <font face=3D"monospace, monospace">std::get&=
lt;1&gt;(t)</font> returns nothing. That much isn&#39;t controversial to me=
..</div><div>I understand that you want to be able to construct such an obje=
ct via=C2=A0<font face=3D"monospace, monospace">std::make_tuple(1, void())<=
/font>. I consider <i>that</i>=C2=A0part controversial.</div><div><br></div=
><div>=C2=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 clas=
s=3D"gmail_extra"><div class=3D"gmail_quote"><div> To be clear on why that =
is, simply imagine a make_tuple-like facility that takes the arguments by v=
alue. What do you think the signature of that function is for a tuple&lt;in=
t, int&gt;? What do you think the signature is for tuple&lt;int, void, int&=
gt;? What about tuple&lt;void&gt;? What about tuple&lt;&gt;? Note that the =
last two cases are <i>very</i>=C2=A0different. The former is a unary functi=
on that takes void. The latter is a true, nullary function. They are in no =
way the same thing. Do not flatten unary void to nullary. They are distinct=
..</div></div></div></div></blockquote><div><br></div><div>I agree that <fon=
t face=3D"monospace, monospace">std::tuple&lt;void&gt;</font>, if it were a=
llowed, would be a different type from <font face=3D"monospace, monospace">=
std::tuple&lt;&gt;</font>, in exactly the same way that=C2=A0<font face=3D"=
monospace, monospace">boost::mpl::list&lt;void&gt;</font> is a different ty=
pe from <font face=3D"monospace, monospace">boost::mpl::list&lt;&gt;</font>=
..</div><div>However, <font face=3D"monospace, monospace">int(*)(void)</font=
> and <font face=3D"monospace, monospace">int(*)()</font> denote the same t=
ype; always have, always will, and IMO always should.</div><div>I don&#39;t=
 know how to reconcile <font face=3D"monospace, monospace">std::tuple&lt;vo=
id&gt;</font> with <font face=3D"monospace, monospace">make_tuple</font>. I=
 don&#39;t think that introducing a new &quot;unary void&quot; is the right=
 way to do it. Instead of introducing &quot;unary void&quot;, I would rathe=
r leave <font face=3D"monospace, monospace">std::tuple&lt;void&gt;</font> i=
ll-formed, or even say that it is well-formed but that instances of it cann=
ot be constructed via any kind of <font face=3D"monospace, monospace">make_=
tuple</font>.</div><div><br></div><div>=E2=80=93Arthur</div></div></div></d=
iv>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--f46d0438940f710f8e051c78075a--

.


Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Tue, 4 Aug 2015 02:00:41 -0700 (PDT)
Raw View
------=_Part_119_569798403.1438678841136
Content-Type: multipart/alternative;
 boundary="----=_Part_120_350790949.1438678841136"

------=_Part_120_350790949.1438678841136
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

How about just defining that void behaves like an empty struct? This avoids=
=20
us having to discuss every particular case. There are still the potentials=
=20
for code breakage with tricky SFINAE but I don't see how that can ever be=
=20
avoided if we change the behaviour of void at all. Note: I don't mean that=
=20
void should BE an empty struct in that you can inherit from it, but that it=
=20
acts like one when used in code.

Den tisdag 4 augusti 2015 kl. 10:25:31 UTC+2 skrev Arthur O'Dwyer:
>
> On Tue, Aug 4, 2015 at 12:44 AM, 'Matt Calabrese' via ISO C++ Standard -=
=20
> Future Proposals <std-pr...@isocpp.org <javascript:>> wrote:
>
>>
>> On Mon, Aug 3, 2015 at 11:55 PM, Arthur O'Dwyer <arthur....@gmail.com=20
>> <javascript:>> wrote:=20
>>>
>>> Notice that std::promise<void>::set_value(void) isn't exactly the same=
=20
>>> case as what I'm talking about. In the set_value case, we merely need t=
o=20
>>> allow a parameter to have a type that is dependent yet void. C++ alread=
y=20
>>> allows void types for non-dependently-typed parameters, so this should =
be=20
>>> relatively simple. I'm talking about actually using type deduction to=
=20
>>> *deduce* void for a parameter of *deduced* type.
>>>
>>
>> I know the case you are talking about -- I already explained how it'd be=
=20
>> handled, I'm just trying to show all cases for clarity and to show its=
=20
>> consistency with the non-deduced version. I don't believe that we should=
=20
>> change one without changing the other. Ideally they are consistent with =
one=20
>> another.
>>
>> However, even before we get there, I'm seeing repeatedly that you and I=
=20
>>> disagree about the sensicality of a "unary function taking void".
>>> In my world, that's impossible; a function whose argument list is=20
>>> equivalent to void is nullary *by definition*.
>>>
>>
>> Then you are being inconsistent in what you think void means. You've=20
>> already stated that you understand what tuple<int, void> is and it is=20
>> consistent with what I've stated. This effectively implies that you acce=
pt=20
>> unary void is a sensible construct.
>>
>
> Not really. It means I see what you mean by tuple<int,void> =E2=80=94 you=
 mean an=20
> object t such that std::tuple_size(t) returns 2, std::get<0>(t) returns=
=20
> an int and std::get<1>(t) returns nothing. That much isn't controversial=
=20
> to me.
> I understand that you want to be able to construct such an object via std=
::make_tuple(1,=20
> void()). I consider *that* part controversial.
>
> =20
>
>> To be clear on why that is, simply imagine a make_tuple-like facility=20
>> that takes the arguments by value. What do you think the signature of th=
at=20
>> function is for a tuple<int, int>? What do you think the signature is fo=
r=20
>> tuple<int, void, int>? What about tuple<void>? What about tuple<>? Note=
=20
>> that the last two cases are *very* different. The former is a unary=20
>> function that takes void. The latter is a true, nullary function. They a=
re=20
>> in no way the same thing. Do not flatten unary void to nullary. They are=
=20
>> distinct.
>>
>
> I agree that std::tuple<void>, if it were allowed, would be a different=
=20
> type from std::tuple<>, in exactly the same way that=20
> boost::mpl::list<void> is a different type from boost::mpl::list<>.
> However, int(*)(void) and int(*)() denote the same type; always have,=20
> always will, and IMO always should.
> I don't know how to reconcile std::tuple<void> with make_tuple. I don't=
=20
> think that introducing a new "unary void" is the right way to do it.=20
> Instead of introducing "unary void", I would rather leave std::tuple<void=
>=20
> ill-formed, or even say that it is well-formed but that instances of it=
=20
> cannot be constructed via any kind of make_tuple.
>
> =E2=80=93Arthur
>

--=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_120_350790949.1438678841136
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">How about just defining that void behaves like an empty st=
ruct? This avoids us having to discuss every particular case. There are sti=
ll the potentials for code breakage with tricky SFINAE but I don&#39;t see =
how that can ever be avoided if we change the behaviour of void at all. Not=
e: I don&#39;t mean that void should BE an empty struct in that you can inh=
erit from it, but that it acts like one when used in code.<br><br>Den tisda=
g 4 augusti 2015 kl. 10:25:31 UTC+2 skrev Arthur O&#39;Dwyer:<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">On Tue, Aug 4, 2015 at 12:4=
4 AM, &#39;Matt Calabrese&#39; via ISO C++ Standard - Future Proposals <spa=
n dir=3D"ltr">&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-=
mailto=3D"s_LQOGDSDwAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;ja=
vascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;r=
eturn true;">std-pr...@isocpp.org</a>&gt;</span> wrote:<br><div><div class=
=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><br><=
div class=3D"gmail_quote"><span>On Mon, Aug 3, 2015 at 11:55 PM, Arthur O&#=
39;Dwyer <span dir=3D"ltr">&lt;<a href=3D"javascript:" target=3D"_blank" gd=
f-obfuscated-mailto=3D"s_LQOGDSDwAJ" rel=3D"nofollow" onmousedown=3D"this.h=
ref=3D&#39;javascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javas=
cript:&#39;;return true;">arthur....@gmail.com</a>&gt;</span> wrote:=C2=A0<=
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><div class=3D"gmail_quo=
te"><div>Notice that std::promise&lt;void&gt;::set_value(<wbr>void) isn&#39=
;t exactly the same case as what I&#39;m talking about. In the set_value ca=
se, we merely need to allow a parameter to have a type that is dependent ye=
t void. C++ already allows void types for non-dependently-typed parameters,=
 so this should be relatively simple. I&#39;m talking about actually using =
type deduction to <i>deduce</i> <font face=3D"monospace, monospace">void</f=
ont> for a parameter of <i>deduced</i> type.</div></div></div></div></block=
quote><div><br></div></span><div>I know the case you are talking about -- I=
 already explained how it&#39;d be handled, I&#39;m just trying to show all=
 cases for clarity and to show its consistency with the non-deduced version=
.. I don&#39;t believe that we should change one without changing the other.=
 Ideally they are consistent with one another.</div><span><div><br></div><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"><div><div class=3D"gmail_quot=
e"><div>However, even before we get there, I&#39;m seeing repeatedly that y=
ou and I disagree about the sensicality of a &quot;unary function taking <f=
ont face=3D"monospace, monospace">void</font>&quot;.<br></div><div>In my wo=
rld, that&#39;s impossible; a function whose argument list is equivalent to=
 <font face=3D"monospace, monospace">void</font> is nullary <i>by definitio=
n</i>.</div></div></div></div></blockquote><div><br></div></span><div>Then =
you are being inconsistent in what you think void means. You&#39;ve already=
 stated that you understand what tuple&lt;int, void&gt; is and it is consis=
tent with what I&#39;ve stated. This effectively implies that you accept un=
ary void is a sensible construct.</div></div></div></div></blockquote><div>=
<br></div><div>Not really. It means I see what you mean by<font face=3D"mon=
ospace, monospace"> tuple&lt;int,void&gt;</font> =E2=80=94 you mean an obje=
ct <font face=3D"monospace, monospace">t</font> such that <font face=3D"mon=
ospace, monospace">std::tuple_size(t)</font> returns <font face=3D"monospac=
e, monospace">2</font>,=C2=A0<font face=3D"monospace, monospace">std::get&l=
t;0&gt;(t)</font> returns an int and <font face=3D"monospace, monospace">st=
d::get&lt;1&gt;(t)</font> returns nothing. That much isn&#39;t controversia=
l to me.</div><div>I understand that you want to be able to construct such =
an object via=C2=A0<font face=3D"monospace, monospace">std::make_tuple(1, v=
oid())</font>. I consider <i>that</i>=C2=A0part controversial.</div><div><b=
r></div><div>=C2=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"><d=
iv><div class=3D"gmail_quote"><div> To be clear on why that is, simply imag=
ine a make_tuple-like facility that takes the arguments by value. What do y=
ou think the signature of that function is for a tuple&lt;int, int&gt;? Wha=
t do you think the signature is for tuple&lt;int, void, int&gt;? What about=
 tuple&lt;void&gt;? What about tuple&lt;&gt;? Note that the last two cases =
are <i>very</i>=C2=A0different. The former is a unary function that takes v=
oid. The latter is a true, nullary function. They are in no way the same th=
ing. Do not flatten unary void to nullary. They are distinct.</div></div></=
div></div></blockquote><div><br></div><div>I agree that <font face=3D"monos=
pace, monospace">std::tuple&lt;void&gt;</font>, if it were allowed, would b=
e a different type from <font face=3D"monospace, monospace">std::tuple&lt;&=
gt;</font>, in exactly the same way that=C2=A0<font face=3D"monospace, mono=
space">boost::mpl::list&lt;void&gt;</font> is a different type from <font f=
ace=3D"monospace, monospace">boost::mpl::list&lt;&gt;</font>.</div><div>How=
ever, <font face=3D"monospace, monospace">int(*)(void)</font> and <font fac=
e=3D"monospace, monospace">int(*)()</font> denote the same type; always hav=
e, always will, and IMO always should.</div><div>I don&#39;t know how to re=
concile <font face=3D"monospace, monospace">std::tuple&lt;void&gt;</font> w=
ith <font face=3D"monospace, monospace">make_tuple</font>. I don&#39;t thin=
k that introducing a new &quot;unary void&quot; is the right way to do it. =
Instead of introducing &quot;unary void&quot;, I would rather leave <font f=
ace=3D"monospace, monospace">std::tuple&lt;void&gt;</font> ill-formed, or e=
ven say that it is well-formed but that instances of it cannot be construct=
ed via any kind of <font face=3D"monospace, monospace">make_tuple</font>.</=
div><div><br></div><div>=E2=80=93Arthur</div></div></div></div>
</blockquote></div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_120_350790949.1438678841136--
------=_Part_119_569798403.1438678841136--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Tue, 4 Aug 2015 02:06:46 -0700
Raw View
--089e0149bc7c0a9ffd051c789bcd
Content-Type: text/plain; charset=UTF-8

On Tue, Aug 4, 2015 at 1:25 AM, Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
wrote:
>
> I understand that you want to be able to construct such an object via std::make_tuple(1,
> void()). I consider *that* part controversial.
>
Yes, you say it's "controversial" but you don't ever explain why you think
it doesn't make sense. It makes perfect sense and I've even given
real-world examples in this thread that directly involve make_tuple and
void. I may be the most active person in this thread right now, but I am
not at all unique in this -- the notion that void should be like any other
type is understood by many already in the generic programming world. All
you have stated is simply that you intuitively feel a certain function type
is "nonsensical" because it contains void in it. I'm sorry, but unless you
have an explanation for why you think that's the case, then I'm simply not
going to give your personal intuition any credit at all. Actually address
*what* about it you think is nonsensical if you want to have a serious
discussion about this, and in doing so, explain how your view would affect
the examples already presented in this thread in a positive way.

I don't know how to reconcile std::tuple<void> with make_tuple. I don't
> think that introducing a new "unary void" is the right way to do it.
> Instead of introducing "unary void", I would rather leave std::tuple<void>
> ill-formed, or even say that it is well-formed but that instances of it
> cannot be constructed via any kind of make_tuple.
>
That's the kind of special casing we are removing and there is nothing
illogical with a single void parameter. What do you think you are
accomplishing by having it illegal? How many examples of it being used in
practice do I have to give (I've already given several)? I apologize that
I'm getting really annoyed here and it's starting to show, but PLEASE
actually back up your arguments or I'm going to eventually just stop taking
your replies seriously.

In an attempt to actually make progress here, let's back up. What of the
following do you disagree with and why? Please do take the "why" part
seriously.

we are trying to remove the special casing that is necessary in generic
code when a dependent type may be void.
void can be thought of as a complete, empty, regular type (a formulation of
the change that we are proposing, critique this if you want).
tuple<int, int> is a sensible type that has an int member and another int
member.
tuple<void, int> is a sensible type that has a void member and an int
member (you've already agreed to this).
the construction of a tuple should be syntactically consistent whether it
is a tuple<int, float> or tuple<double, char> such that it can easily be
constructed when the types are dependent.
the construction of a tuple should be syntactically consistent whether it
is a tuple<int, float> or tuple<int, void> such that it can easily be
constructed when the types are dependent.
having make_tuple work with void arguments eliminates special-casing in
generic code.
have make_tuple fail to work when one of the types is void forces users to
special-case their code when an operand would be void.

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
ue, Aug 4, 2015 at 1:25 AM, Arthur O&#39;Dwyer <span dir=3D"ltr">&lt;<a hre=
f=3D"mailto:arthur.j.odwyer@gmail.com" target=3D"_blank">arthur.j.odwyer@gm=
ail.com</a>&gt;</span> wrote:<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 class=3D"gmail_extra"><div class=3D"gmail_quote"><div>I understand t=
hat you want to be able to construct such an object via=C2=A0<font face=3D"=
monospace, monospace">std::make_tuple(1, void())</font>. I consider <i>that=
</i>=C2=A0part controversial.</div></div></div></div></blockquote><div>Yes,=
 you say it&#39;s &quot;controversial&quot; but you don&#39;t ever explain =
why you think it doesn&#39;t make sense. It makes perfect sense and I&#39;v=
e even given real-world examples in this thread that directly involve make_=
tuple and void. I may be the most active person in this thread right now, b=
ut I am not at all unique in this -- the notion that void should be like an=
y other type is understood by many already in the generic programming world=
.. All you have stated is simply that you intuitively feel a certain functio=
n type is &quot;nonsensical&quot; because it contains void in it. I&#39;m s=
orry, but unless you have an explanation for why you think that&#39;s the c=
ase, then I&#39;m simply not going to give your personal intuition any cred=
it at all. Actually address <i>what</i> about it you think is nonsensical i=
f you want to have a serious discussion about this, and in doing so, explai=
n how your view would affect the examples already presented in this thread =
in a positive way.</div><div><br></div><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div =
dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div></di=
v><div>I don&#39;t know how to reconcile <font face=3D"monospace, monospace=
">std::tuple&lt;void&gt;</font> with <font face=3D"monospace, monospace">ma=
ke_tuple</font>. I don&#39;t think that introducing a new &quot;unary void&=
quot; is the right way to do it. Instead of introducing &quot;unary void&qu=
ot;, I would rather leave <font face=3D"monospace, monospace">std::tuple&lt=
;void&gt;</font> ill-formed, or even say that it is well-formed but that in=
stances of it cannot be constructed via any kind of <font face=3D"monospace=
, monospace">make_tuple</font>.</div></div></div></div></blockquote><div>Th=
at&#39;s the kind of special casing we are removing and there is nothing il=
logical with a single void parameter. What do you think you are accomplishi=
ng by having it illegal? How many examples of it being used in practice do =
I have to give (I&#39;ve already given several)? I apologize that I&#39;m g=
etting really annoyed here and it&#39;s starting to show, but PLEASE actual=
ly back up your arguments or I&#39;m going to eventually just stop taking y=
our replies seriously.</div><div><br></div><div>In an attempt to actually m=
ake progress here, let&#39;s back up. What of the following do you disagree=
 with and why? Please do take the &quot;why&quot; part seriously.</div><div=
><br></div><div>we are trying to remove the special casing that is necessar=
y in generic code when a dependent type may be void.</div><div>void can be =
thought of as a complete, empty, regular type (a formulation of the change =
that we are proposing, critique this if you want).</div><div>tuple&lt;int, =
int&gt; is a sensible type that has an int member and another int member.</=
div><div>tuple&lt;void, int&gt; is a sensible type that has a void member a=
nd an int member (you&#39;ve already agreed to this).</div><div>the constru=
ction of a tuple should be syntactically consistent whether it is a tuple&l=
t;int, float&gt; or tuple&lt;double, char&gt; such that it can easily be co=
nstructed when the types are dependent.</div><div>the construction of a tup=
le should be syntactically consistent whether it is a tuple&lt;int, float&g=
t; or tuple&lt;int, void&gt; such that it can easily be constructed when th=
e types are dependent.</div><div>having make_tuple work with void arguments=
 eliminates special-casing in generic code.</div><div>have make_tuple fail =
to work when one of the types is void forces users to special-case their co=
de when an operand would be void.</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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--089e0149bc7c0a9ffd051c789bcd--

.


Author: Roland Bock <rbock@eudoxos.de>
Date: Tue, 04 Aug 2015 11:12:23 +0200
Raw View
This is a multi-part message in MIME format.
--------------050601060905070603060304
Content-Type: text/plain; charset=UTF-8

On 2015-08-04 10:02, 'Matt Calabrese' via ISO C++ Standard - Future
Proposals wrote:
> On Tue, Aug 4, 2015 at 12:32 AM, Roland Bock <rbock@eudoxos.de
> <mailto:rbock@eudoxos.de>> wrote:
>
>
>     How about binary functions?
>
>     void foo0();              // zero parameters
>     void foo1(void);          // still zero parameters (you say)
>     void foo2(void, void);    // ???
>
>     and how about
>
>     void foo2(int, void);     // ???
>     void foo2(void, int);     // ???
>
>     I would prefer all of them to be different, foo0 having zero
>     parameters, foo1 having one parameters, foo2 having two parameters.
>
>
> Yes!!! They are all logically different, we realistically just can't
> use the syntax for foo1.
>
>     We could however introduce a new thing, e.g. std::none, that could
>     be designed from afresh and have all the nice features we would
>     like to see in void
>
>
> Unfortunately that wouldn't help generic code unless everyone just
> updated all of their code over night and nobody instantiated templates
> with void, which realistically wouldn't happen.

Right. Note to self: Do not write to this list too often, when suffering
from the flu.

> void is going to stay so ideally we actually fix it in some way. IMO,
> we're really close to getting there. The only thing we don't have IMHO
> is a good syntax for representing a unary void function when void is
> not dependent. It's fine if there is an odd-ball syntax for it because
> the dependent case is the one that comes up in generic code. You
> wouldn't need to use the weird syntax there.
>
> One possible solution -- we could have unary void functions declared as:
>
> /////
> void foo(explicit void) {}
> /////
>
Looks a bit weird, but sure looks like an option for solving the dilemma...


--

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

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

<html>
  <head>
    <meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Type=
">
  </head>
  <body bgcolor=3D"#FFFFFF" text=3D"#000000">
    <div class=3D"moz-cite-prefix">On 2015-08-04 10:02, 'Matt Calabrese'
      via ISO C++ Standard - Future Proposals wrote:<br>
    </div>
    <blockquote
cite=3D"mid:CANh8DEmob9YeWR_iGYKa6RwmtLfuGCSAyozKGng4gouTpmobHg@mail.gmail.=
com"
      type=3D"cite">
      <div dir=3D"ltr">
        <div class=3D"gmail_extra">
          <div class=3D"gmail_quote">On Tue, Aug 4, 2015 at 12:32 AM,
            Roland Bock <span dir=3D"ltr">&lt;<a moz-do-not-send=3D"true"
                href=3D"mailto:rbock@eudoxos.de" target=3D"_blank">rbock@eu=
doxos.de</a>&gt;</span>
            wrote:
            <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0
              .8ex;border-left:1px #ccc solid;padding-left:1ex">
              <div bgcolor=3D"#FFFFFF" text=3D"#000000"> <br>
                How about binary functions?<br>
                <br>
                <tt>void foo0();=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // zero parameters</tt><tt><br>
                </tt><tt>void foo1(void);=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 // still zero
                  parameters (you say)</tt><tt><br>
                </tt><tt>void foo2(void, void);=C2=A0=C2=A0=C2=A0 // ???</t=
t><tt><br>
                </tt><br>
                and how about <br>
                <br>
                <tt>void foo2(int, void);=C2=A0=C2=A0=C2=A0=C2=A0 // ???</t=
t><tt><br>
                </tt><tt>void foo2(void, int);=C2=A0=C2=A0=C2=A0=C2=A0 // ?=
??</tt><br>
                <br>
                I would prefer all of them to be different, foo0 having
                zero parameters, foo1 having one parameters, foo2 having
                two parameters.<br>
              </div>
            </blockquote>
            <div><br>
            </div>
            <div>Yes!!! They are all logically different, we
              realistically just can't use the syntax for foo1.</div>
            <div><br>
            </div>
            <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0
              .8ex;border-left:1px #ccc solid;padding-left:1ex">
              <div bgcolor=3D"#FFFFFF" text=3D"#000000">We could however
                introduce a new thing, e.g. std::none, that could be
                designed from afresh and have all the nice features we
                would like to see in void<br>
              </div>
            </blockquote>
            <div><br>
            </div>
            <div>Unfortunately that wouldn't help generic code unless
              everyone just updated all of their code over night and
              nobody instantiated templates with void, which
              realistically wouldn't happen.</div>
          </div>
        </div>
      </div>
    </blockquote>
    <br>
    Right. Note to self: Do not write to this list too often, when
    suffering from the flu.<br>
    <br>
    <blockquote
cite=3D"mid:CANh8DEmob9YeWR_iGYKa6RwmtLfuGCSAyozKGng4gouTpmobHg@mail.gmail.=
com"
      type=3D"cite">
      <div dir=3D"ltr">
        <div class=3D"gmail_extra">
          <div class=3D"gmail_quote">
            <div> void is going to stay so ideally we actually fix it in
              some way. IMO, we're really close to getting there. The
              only thing we don't have IMHO is a good syntax for
              representing a unary void function when void is not
              dependent. It's fine if there is an odd-ball syntax for it
              because the dependent case is the one that comes up in
              generic code. You wouldn't need to use the weird syntax
              there.</div>
            <div><br>
            </div>
            <div>One possible solution -- we could have unary void
              functions declared as:</div>
            <div><br>
            </div>
            <div>/////</div>
            <div>void foo(explicit void) {}</div>
            <div>/////</div>
            <div><br>
            </div>
          </div>
        </div>
      </div>
    </blockquote>
    Looks a bit weird, but sure looks like an option for solving the
    dilemma...<br>
    <br>
    <br>
  </body>
</html>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--------------050601060905070603060304--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Tue, 4 Aug 2015 02:14:33 -0700
Raw View
--001a1134fd40e8725e051c78b6d1
Content-Type: text/plain; charset=UTF-8

On Tue, Aug 4, 2015 at 2:00 AM, Bengt Gustafsson <
bengt.gustafsson@beamways.com> wrote:

> How about just defining that void behaves like an empty struct? This
> avoids us having to discuss every particular case. There are still the
> potentials for code breakage with tricky SFINAE but I don't see how that
> can ever be avoided if we change the behaviour of void at all.
>

Thank you, this is what I'm saying! I don't even really care about the
syntactic sugar regarding construction if it's considered too magical or
prone to more breakage. Just having void be equivalent to an empty struct
that is regular is all that is necessary to have it work in generic code
and eliminate special casing. I don't understand the hang up on this.

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
ue, Aug 4, 2015 at 2:00 AM, Bengt Gustafsson <span dir=3D"ltr">&lt;<a href=
=3D"mailto:bengt.gustafsson@beamways.com" target=3D"_blank">bengt.gustafsso=
n@beamways.com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div=
 dir=3D"ltr">How about just defining that void behaves like an empty struct=
? This avoids us having to discuss every particular case. There are still t=
he potentials for code breakage with tricky SFINAE but I don&#39;t see how =
that can ever be avoided if we change the behaviour of void at all.</div></=
blockquote><div><br></div><div>Thank you, this is what I&#39;m saying! I do=
n&#39;t even really care about the syntactic sugar regarding construction i=
f it&#39;s considered too magical or prone to more breakage. Just having vo=
id be equivalent to an empty struct that is regular is all that is necessar=
y to have it work in generic code and eliminate special casing. I don&#39;t=
 understand the hang up on this.</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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a1134fd40e8725e051c78b6d1--

.


Author: "'Johannes Schaub' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Tue, 4 Aug 2015 11:40:09 +0200
Raw View
--001a113ff8127b723b051c79122f
Content-Type: text/plain; charset=UTF-8

If we are already in oddballs mode, why not express the nondependent case
by dependent types

template<typename T = void>
void f(typename void_t<T>::type);

Am 04.08.2015 10:02 schrieb "'Matt Calabrese' via ISO C++ Standard - Future
Proposals" <std-proposals@isocpp.org>:
>
> On Tue, Aug 4, 2015 at 12:32 AM, Roland Bock <rbock@eudoxos.de> wrote:
>>
>>
>> How about binary functions?
>>
>> void foo0();              // zero parameters
>> void foo1(void);          // still zero parameters (you say)
>> void foo2(void, void);    // ???
>>
>> and how about
>>
>> void foo2(int, void);     // ???
>> void foo2(void, int);     // ???
>>
>> I would prefer all of them to be different, foo0 having zero parameters,
foo1 having one parameters, foo2 having two parameters.
>
>
> Yes!!! They are all logically different, we realistically just can't use
the syntax for foo1.
>
>> We could however introduce a new thing, e.g. std::none, that could be
designed from afresh and have all the nice features we would like to see in
void
>
>
> Unfortunately that wouldn't help generic code unless everyone just
updated all of their code over night and nobody instantiated templates with
void, which realistically wouldn't happen. void is going to stay so ideally
we actually fix it in some way. IMO, we're really close to getting there.
The only thing we don't have IMHO is a good syntax for representing a unary
void function when void is not dependent. It's fine if there is an odd-ball
syntax for it because the dependent case is the one that comes up in
generic code. You wouldn't need to use the weird syntax there.
>
> One possible solution -- we could have unary void functions declared as:
>
> /////
> void foo(explicit void) {}
> /////
>
> This is syntax that was illegal before, introduces no new keywords or
types, and doesn't look too obscure. There are probably many alternatives
and I'm not saying this is what it should be, we'd just need to pick one
that makes the most sense.
>

--

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

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

<p dir=3D"ltr">If we are already in oddballs mode, why not express the nond=
ependent case by dependent types</p>
<p dir=3D"ltr">template&lt;typename T =3D void&gt;<br>
void f(typename void_t&lt;T&gt;::type);<br></p>
<p dir=3D"ltr">Am 04.08.2015 10:02 schrieb &quot;&#39;Matt Calabrese&#39; v=
ia ISO C++ Standard - Future Proposals&quot; &lt;<a href=3D"mailto:std-prop=
osals@isocpp.org">std-proposals@isocpp.org</a>&gt;:<br>
&gt;<br>
&gt; On Tue, Aug 4, 2015 at 12:32 AM, Roland Bock &lt;<a href=3D"mailto:rbo=
ck@eudoxos.de">rbock@eudoxos.de</a>&gt; wrote:<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; How about binary functions?<br>
&gt;&gt;<br>
&gt;&gt; void foo0();=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0 // zero parameters<br>
&gt;&gt; void foo1(void);=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 // still zero parameters (you say)<br>
&gt;&gt; void foo2(void, void);=C2=A0=C2=A0=C2=A0 // ???<br>
&gt;&gt;<br>
&gt;&gt; and how about <br>
&gt;&gt;<br>
&gt;&gt; void foo2(int, void);=C2=A0=C2=A0=C2=A0=C2=A0 // ???<br>
&gt;&gt; void foo2(void, int);=C2=A0=C2=A0=C2=A0=C2=A0 // ???<br>
&gt;&gt;<br>
&gt;&gt; I would prefer all of them to be different, foo0 having zero param=
eters, foo1 having one parameters, foo2 having two parameters.<br>
&gt;<br>
&gt;<br>
&gt; Yes!!! They are all logically different, we realistically just can&#39=
;t use the syntax for foo1.<br>
&gt;<br>
&gt;&gt; We could however introduce a new thing, e.g. std::none, that could=
 be designed from afresh and have all the nice features we would like to se=
e in void<br>
&gt;<br>
&gt;<br>
&gt; Unfortunately that wouldn&#39;t help generic code unless everyone just=
 updated all of their code over night and nobody instantiated templates wit=
h void, which realistically wouldn&#39;t happen. void is going to stay so i=
deally we actually fix it in some way. IMO, we&#39;re really close to getti=
ng there. The only thing we don&#39;t have IMHO is a good syntax for repres=
enting a unary void function when void is not dependent. It&#39;s fine if t=
here is an odd-ball syntax for it because the dependent case is the one tha=
t comes up in generic code. You wouldn&#39;t need to use the weird syntax t=
here.<br>
&gt;<br>
&gt; One possible solution -- we could have unary void functions declared a=
s:<br>
&gt;<br>
&gt; /////<br>
&gt; void foo(explicit void) {}<br>
&gt; /////<br>
&gt;<br>
&gt; This is syntax that was illegal before, introduces no new keywords or =
types, and doesn&#39;t look too obscure. There are probably many alternativ=
es and I&#39;m not saying this is what it should be, we&#39;d just need to =
pick one that makes the most sense.=C2=A0<br>
&gt;</p>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a113ff8127b723b051c79122f--

.


Author: "'Johannes Schaub' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Tue, 4 Aug 2015 11:46:20 +0200
Raw View
--001a113f97d8977c9c051c79287d
Content-Type: text/plain; charset=UTF-8

Altermatively just give the void parameter a name. A named parameter
shouldn't catch the special case of meaning an empty parameter list.

Am 04.08.2015 11:40 schrieb "Johannes Schaub" <
schaub.johannes@googlemail.com>:
>
> If we are already in oddballs mode, why not express the nondependent case
by dependent types
>
> template<typename T = void>
> void f(typename void_t<T>::type);
>
> Am 04.08.2015 10:02 schrieb "'Matt Calabrese' via ISO C++ Standard -
Future Proposals" <std-proposals@isocpp.org>:
> >
> > On Tue, Aug 4, 2015 at 12:32 AM, Roland Bock <rbock@eudoxos.de> wrote:
> >>
> >>
> >> How about binary functions?
> >>
> >> void foo0();              // zero parameters
> >> void foo1(void);          // still zero parameters (you say)
> >> void foo2(void, void);    // ???
> >>
> >> and how about
> >>
> >> void foo2(int, void);     // ???
> >> void foo2(void, int);     // ???
> >>
> >> I would prefer all of them to be different, foo0 having zero
parameters, foo1 having one parameters, foo2 having two parameters.
> >
> >
> > Yes!!! They are all logically different, we realistically just can't
use the syntax for foo1.
> >
> >> We could however introduce a new thing, e.g. std::none, that could be
designed from afresh and have all the nice features we would like to see in
void
> >
> >
> > Unfortunately that wouldn't help generic code unless everyone just
updated all of their code over night and nobody instantiated templates with
void, which realistically wouldn't happen. void is going to stay so ideally
we actually fix it in some way. IMO, we're really close to getting there.
The only thing we don't have IMHO is a good syntax for representing a unary
void function when void is not dependent. It's fine if there is an odd-ball
syntax for it because the dependent case is the one that comes up in
generic code. You wouldn't need to use the weird syntax there.
> >
> > One possible solution -- we could have unary void functions declared as:
> >
> > /////
> > void foo(explicit void) {}
> > /////
> >
> > This is syntax that was illegal before, introduces no new keywords or
types, and doesn't look too obscure. There are probably many alternatives
and I'm not saying this is what it should be, we'd just need to pick one
that makes the most sense.
> >

--

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

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

<p dir=3D"ltr">Altermatively just give the void parameter a name. A named p=
arameter shouldn&#39;t catch the special case of meaning an empty parameter=
 list.</p>
<p dir=3D"ltr">Am 04.08.2015 11:40 schrieb &quot;Johannes Schaub&quot; &lt;=
<a href=3D"mailto:schaub.johannes@googlemail.com">schaub.johannes@googlemai=
l.com</a>&gt;:<br>
&gt;<br>
&gt; If we are already in oddballs mode, why not express the nondependent c=
ase by dependent types<br>
&gt;<br>
&gt; template&lt;typename T =3D void&gt;<br>
&gt; void f(typename void_t&lt;T&gt;::type);<br>
&gt;<br>
&gt; Am 04.08.2015 10:02 schrieb &quot;&#39;Matt Calabrese&#39; via ISO C++=
 Standard - Future Proposals&quot; &lt;<a href=3D"mailto:std-proposals@isoc=
pp.org">std-proposals@isocpp.org</a>&gt;:<br>
&gt; &gt;<br>
&gt; &gt; On Tue, Aug 4, 2015 at 12:32 AM, Roland Bock &lt;<a href=3D"mailt=
o:rbock@eudoxos.de">rbock@eudoxos.de</a>&gt; wrote:<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; How about binary functions?<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; void foo0();=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // zero parameters<br>
&gt; &gt;&gt; void foo1(void);=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 // still zero parameters (you say)<br>
&gt; &gt;&gt; void foo2(void, void);=C2=A0=C2=A0=C2=A0 // ???<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; and how about <br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; void foo2(int, void);=C2=A0=C2=A0=C2=A0=C2=A0 // ???<br>
&gt; &gt;&gt; void foo2(void, int);=C2=A0=C2=A0=C2=A0=C2=A0 // ???<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; I would prefer all of them to be different, foo0 having zero =
parameters, foo1 having one parameters, foo2 having two parameters.<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt; Yes!!! They are all logically different, we realistically just ca=
n&#39;t use the syntax for foo1.<br>
&gt; &gt;<br>
&gt; &gt;&gt; We could however introduce a new thing, e.g. std::none, that =
could be designed from afresh and have all the nice features we would like =
to see in void<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt; Unfortunately that wouldn&#39;t help generic code unless everyone=
 just updated all of their code over night and nobody instantiated template=
s with void, which realistically wouldn&#39;t happen. void is going to stay=
 so ideally we actually fix it in some way. IMO, we&#39;re really close to =
getting there. The only thing we don&#39;t have IMHO is a good syntax for r=
epresenting a unary void function when void is not dependent. It&#39;s fine=
 if there is an odd-ball syntax for it because the dependent case is the on=
e that comes up in generic code. You wouldn&#39;t need to use the weird syn=
tax there.<br>
&gt; &gt;<br>
&gt; &gt; One possible solution -- we could have unary void functions decla=
red as:<br>
&gt; &gt;<br>
&gt; &gt; /////<br>
&gt; &gt; void foo(explicit void) {}<br>
&gt; &gt; /////<br>
&gt; &gt;<br>
&gt; &gt; This is syntax that was illegal before, introduces no new keyword=
s or types, and doesn&#39;t look too obscure. There are probably many alter=
natives and I&#39;m not saying this is what it should be, we&#39;d just nee=
d to pick one that makes the most sense.=C2=A0<br>
&gt; &gt;</p>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a113f97d8977c9c051c79287d--

.


Author: "'Edward Catmur' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Tue, 4 Aug 2015 10:50:24 +0100
Raw View
--047d7b6222e415699c051c79378d
Content-Type: text/plain; charset=UTF-8

Yes! Also, deprecate (void) meaning () outside extern "C" - there's no need
for it, as C++ doesn't have unspecified parameter lists (even in C they're
obsolescent: 6.11.6 "Future language directions - Function declarators").

On Tue, Aug 4, 2015 at 10:46 AM, 'Johannes Schaub' via ISO C++ Standard -
Future Proposals <std-proposals@isocpp.org> wrote:

> Altermatively just give the void parameter a name. A named parameter
> shouldn't catch the special case of meaning an empty parameter list.
>
> Am 04.08.2015 11:40 schrieb "Johannes Schaub" <
> schaub.johannes@googlemail.com>:
> >
> > If we are already in oddballs mode, why not express the nondependent
> case by dependent types
> >
> > template<typename T = void>
> > void f(typename void_t<T>::type);
> >
> > Am 04.08.2015 10:02 schrieb "'Matt Calabrese' via ISO C++ Standard -
> Future Proposals" <std-proposals@isocpp.org>:
> > >
> > > On Tue, Aug 4, 2015 at 12:32 AM, Roland Bock <rbock@eudoxos.de> wrote:
> > >>
> > >>
> > >> How about binary functions?
> > >>
> > >> void foo0();              // zero parameters
> > >> void foo1(void);          // still zero parameters (you say)
> > >> void foo2(void, void);    // ???
> > >>
> > >> and how about
> > >>
> > >> void foo2(int, void);     // ???
> > >> void foo2(void, int);     // ???
> > >>
> > >> I would prefer all of them to be different, foo0 having zero
> parameters, foo1 having one parameters, foo2 having two parameters.
> > >
> > >
> > > Yes!!! They are all logically different, we realistically just can't
> use the syntax for foo1.
> > >
> > >> We could however introduce a new thing, e.g. std::none, that could be
> designed from afresh and have all the nice features we would like to see in
> void
> > >
> > >
> > > Unfortunately that wouldn't help generic code unless everyone just
> updated all of their code over night and nobody instantiated templates with
> void, which realistically wouldn't happen. void is going to stay so ideally
> we actually fix it in some way. IMO, we're really close to getting there.
> The only thing we don't have IMHO is a good syntax for representing a unary
> void function when void is not dependent. It's fine if there is an odd-ball
> syntax for it because the dependent case is the one that comes up in
> generic code. You wouldn't need to use the weird syntax there.
> > >
> > > One possible solution -- we could have unary void functions declared
> as:
> > >
> > > /////
> > > void foo(explicit void) {}
> > > /////
> > >
> > > This is syntax that was illegal before, introduces no new keywords or
> types, and doesn't look too obscure. There are probably many alternatives
> and I'm not saying this is what it should be, we'd just need to pick one
> that makes the most sense.
> > >
>
> --
>
> ---
> You received this message because you are subscribed to a topic in the
> Google Groups "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/a/isocpp.org/d/topic/std-proposals/05prNzycvYU/unsubscribe
> .
> To unsubscribe from this group and all its topics, 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/.

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

<div dir=3D"ltr">Yes! Also, deprecate (void) meaning () outside extern &quo=
t;C&quot; - there&#39;s no need for it, as C++ doesn&#39;t have unspecified=
 parameter lists (even in C they&#39;re obsolescent: 6.11.6 &quot;Future la=
nguage directions - Function declarators&quot;).</div><div class=3D"gmail_e=
xtra"><br><div class=3D"gmail_quote">On Tue, Aug 4, 2015 at 10:46 AM, &#39;=
Johannes Schaub&#39; via ISO C++ Standard - Future Proposals <span dir=3D"l=
tr">&lt;<a href=3D"mailto:std-proposals@isocpp.org" target=3D"_blank">std-p=
roposals@isocpp.org</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quo=
te" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"=
><p dir=3D"ltr">Altermatively just give the void parameter a name. A named =
parameter shouldn&#39;t catch the special case of meaning an empty paramete=
r list.</p><div class=3D"HOEnZb"><div class=3D"h5">
<p dir=3D"ltr">Am 04.08.2015 11:40 schrieb &quot;Johannes Schaub&quot; &lt;=
<a href=3D"mailto:schaub.johannes@googlemail.com" target=3D"_blank">schaub.=
johannes@googlemail.com</a>&gt;:<br>
&gt;<br>
&gt; If we are already in oddballs mode, why not express the nondependent c=
ase by dependent types<br>
&gt;<br>
&gt; template&lt;typename T =3D void&gt;<br>
&gt; void f(typename void_t&lt;T&gt;::type);<br>
&gt;<br>
&gt; Am 04.08.2015 10:02 schrieb &quot;&#39;Matt Calabrese&#39; via ISO C++=
 Standard - Future Proposals&quot; &lt;<a href=3D"mailto:std-proposals@isoc=
pp.org" target=3D"_blank">std-proposals@isocpp.org</a>&gt;:<br>
&gt; &gt;<br>
&gt; &gt; On Tue, Aug 4, 2015 at 12:32 AM, Roland Bock &lt;<a href=3D"mailt=
o:rbock@eudoxos.de" target=3D"_blank">rbock@eudoxos.de</a>&gt; wrote:<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; How about binary functions?<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; void foo0();=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // zero parameters<br>
&gt; &gt;&gt; void foo1(void);=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 // still zero parameters (you say)<br>
&gt; &gt;&gt; void foo2(void, void);=C2=A0=C2=A0=C2=A0 // ???<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; and how about <br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; void foo2(int, void);=C2=A0=C2=A0=C2=A0=C2=A0 // ???<br>
&gt; &gt;&gt; void foo2(void, int);=C2=A0=C2=A0=C2=A0=C2=A0 // ???<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; I would prefer all of them to be different, foo0 having zero =
parameters, foo1 having one parameters, foo2 having two parameters.<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt; Yes!!! They are all logically different, we realistically just ca=
n&#39;t use the syntax for foo1.<br>
&gt; &gt;<br>
&gt; &gt;&gt; We could however introduce a new thing, e.g. std::none, that =
could be designed from afresh and have all the nice features we would like =
to see in void<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt; Unfortunately that wouldn&#39;t help generic code unless everyone=
 just updated all of their code over night and nobody instantiated template=
s with void, which realistically wouldn&#39;t happen. void is going to stay=
 so ideally we actually fix it in some way. IMO, we&#39;re really close to =
getting there. The only thing we don&#39;t have IMHO is a good syntax for r=
epresenting a unary void function when void is not dependent. It&#39;s fine=
 if there is an odd-ball syntax for it because the dependent case is the on=
e that comes up in generic code. You wouldn&#39;t need to use the weird syn=
tax there.<br>
&gt; &gt;<br>
&gt; &gt; One possible solution -- we could have unary void functions decla=
red as:<br>
&gt; &gt;<br>
&gt; &gt; /////<br>
&gt; &gt; void foo(explicit void) {}<br>
&gt; &gt; /////<br>
&gt; &gt;<br>
&gt; &gt; This is syntax that was illegal before, introduces no new keyword=
s or types, and doesn&#39;t look too obscure. There are probably many alter=
natives and I&#39;m not saying this is what it should be, we&#39;d just nee=
d to pick one that makes the most sense.=C2=A0<br>
&gt; &gt;</p>

<p></p>

-- <br>
<br>
--- <br>
You received this message because you are subscribed to a topic in the Goog=
le Groups &quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this topic, visit <a href=3D"https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/05prNzycvYU/unsubscribe" target=3D"_blan=
k">https://groups.google.com/a/isocpp.org/d/topic/std-proposals/05prNzycvYU=
/unsubscribe</a>.<br>
To unsubscribe from this group and all its topics, send an email to <a href=
=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_blank">std-prop=
osals+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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--047d7b6222e415699c051c79378d--

.


Author: Miro Knejp <miro.knejp@gmail.com>
Date: Tue, 4 Aug 2015 15:32:43 +0200
Raw View
> On 04 Aug 2015, at 11:12 , Roland Bock <rbock@eudoxos.de> wrote:
>=20
>> One possible solution -- we could have unary void functions declared as:
>>=20
>> /////
>> void foo(explicit void) {}
>> /////
>>=20
> Looks a bit weird, but sure looks like an option for solving the dilemma.=
...
>=20
Except it requires modifying the callee instead of the caller, so it still =
won=E2=80=99t work with any existing code. Plus, how many people would reme=
mber to put that explicit in there? It is a manual opt-in to make other peo=
ples=E2=80=99 generic code work with a function.

All of this really looks to me like we=E2=80=99re trying to make =E2=80=9Cv=
oid=E2=80=9D be equivalent to the unit types in functional languages. There=
=E2=80=99s a lot of experience with those, so maybe that is a point to star=
t doing research for C++ applicability. Yes, we already have unit types and=
 one can define their own, but the point is that =E2=80=9Cvoid=E2=80=9D cur=
rently is *not* a unit type and that=E2=80=99s what causes generic code hea=
daches.

I don=E2=80=99t see it happening to have foo() and foo(void) define two dif=
ferent functions due to backwards compatibility.

Assuming for a moment that void were a unit type then it should be possible=
 to create instances of it and call foo(void()) and therefore also foo(T())=
 if T=3Dvoid. Unfortunately that breaks existing expression SFINAE as declt=
ype(foo(T())) can be used to filter out deductions with T=3Dvoid. Whether t=
hat is the best way to do it is pretty much irrelevant unless someone can s=
how that it isn=E2=80=99t used in practice.

I know the pain of special casing void but unfortunately the term =E2=80=9C=
the ship has sailed=E2=80=9D is a term that comes up in these forums depres=
singly often. So I don=E2=80=99t think that the syntax void() will become p=
ossible under the assumption that the foo(T()) SFINAE is in use. One would =
probably require some type trait that is specialized for void and returns a=
 magical type that can be used to call unary functions.

template<class T> struct babel_fish { using type =3D T; }
template<> struct babel_fish<void> { using type =3D /* dark magic*/; }

foo(babel_fish<T>());

I just hope we come up with a language solution because this is yet another=
 load of library boilerplate that would need repeating *everywhere*.

--=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: Paul Fultz II <pfultz28@gmail.com>
Date: Tue, 4 Aug 2015 07:57:44 -0700 (PDT)
Raw View
------=_Part_145_1857764164.1438700264364
Content-Type: multipart/alternative;
 boundary="----=_Part_146_1605330648.1438700264364"

------=_Part_146_1605330648.1438700264364
Content-Type: text/plain; charset=UTF-8


On Tuesday, August 4, 2015 at 4:00:41 AM UTC-5, Bengt Gustafsson wrote:
>
> How about just defining that void behaves like an empty struct? This
> avoids us having to discuss every particular case. There are still the
> potentials for code breakage with tricky SFINAE but I don't see how that
> can ever be avoided if we change the behaviour of void at all. Note: I
> don't mean that void should BE an empty struct in that you can inherit from
> it, but that it acts like one when used in code.
>

But having void act like an empty struct, then it becomes a type with one
value. However, `void` should mean a type with zero values(like a function
that doesn't return anything). Of course, changing `void` from having zero
values to one value could break a lot of assumptions made about code. I
think its a bad idea. For some generic code, it may be safe to assume void
as having one value instead of zero, but it would be better to use a
library solution for this instead of baking in potential unsafe type
assumptions into the language.

--

---
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_146_1605330648.1438700264364
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br>On Tuesday, August 4, 2015 at 4:00:41 AM UTC-5, Bengt =
Gustafsson wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr">How about just defining that void behaves like an empty struct? This av=
oids us having to discuss every particular case. There are still the potent=
ials for code breakage with tricky SFINAE but I don&#39;t see how that can =
ever be avoided if we change the behaviour of void at all. Note: I don&#39;=
t mean that void should BE an empty struct in that you can inherit from it,=
 but that it acts like one when used in code.<br></div></blockquote><div>=
=C2=A0<br>But having void act like an empty struct, then it becomes a type =
with one value. However, `void` should mean a type with zero values(like a =
function that doesn&#39;t return anything). Of course, changing `void` from=
 having zero values to one value could break a lot of assumptions made abou=
t code. I think its a bad idea. For some generic code, it may be safe to as=
sume void as having one value instead of zero, but it would be better to us=
e a library solution for this instead of baking in potential unsafe type as=
sumptions into the language.<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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_146_1605330648.1438700264364--
------=_Part_145_1857764164.1438700264364--

.


Author: Jared Grubb <jared.grubb@gmail.com>
Date: Tue, 4 Aug 2015 08:04:52 -0700
Raw View
--Apple-Mail=_7D505FFE-E753-4ABF-BFD4-C43E9EEACDA4
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8


> On Aug 4, 2015, at 01:05, Arthur O'Dwyer <arthur.j.odwyer@gmail.com> wrot=
e:
>=20
> On Tue, Aug 4, 2015 at 12:32 AM, Roland Bock <rbock@eudoxos.de <mailto:rb=
ock@eudoxos.de>> wrote:
> On 2015-08-04 08:55, Arthur O'Dwyer wrote:
>> using Void =3D void;
>>=20
>> void foo() {}  // foo0
>> void foo(Void) {} // foo1
>>=20
>> In my world this is a violation of the ODR; foo0 and foo1 are the same f=
unction.
> Being aware that this is currently the case I wonder if it is a good idea=
?
>=20
> If we could have values of type void, then I doubt that the above makes s=
ense?
> [...]=20
> We could however introduce a new thing, e.g. std::none, that could be des=
igned from afresh and have all the nice features we would like to see in vo=
id.
>=20
> Sounds like std::nullptr_t is already that thing: it's new, it's unitary,=
 it provides relational operators. If you just want something that behaves =
like Python's None, nullptr fits the bill exactly.

The issue there is that is that nullptr is convertible to lots of things (T=
*) and not to a many others (T). That makes it an odd universal void type.

>=20
> Another new-in-C++11, unitary, regular type in the standard library is st=
d::tuple<> (that is, a tuple of zero elements).
>=20
> But the problem is generic programming that needs to work with void param=
eter types (a.k.a. nullary functions) and void return types =E2=80=94 not n=
ullptr_t, not std::tuple<>, but literally and exactly void. Inventing new t=
ypes almost certainly won't solve the problem, because the problem specific=
ally concerns void.

Maybe there should be a new special type defined as decltype(void), which i=
s convertible to and from places where =E2=80=98void=E2=80=99 currently exi=
sts, but is also a regular type. It can be a =E2=80=9Cconduit=E2=80=9D type=
 to make void things regular, but give you an escape hatch back to =E2=80=
=98void=E2=80=99 when it=E2=80=99s needed.

auto v =3D foo();   // type is =E2=80=98decltype(void)=E2=80=99
return v;            // =E2=80=98decltype(void)=E2=80=99 is convertible to =
void return type

We define a name under namespace std that is defined to be that type (like =
nullptr_t does).


>=20
> =E2=80=93Arthur
>=20
> --=20
>=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=
 email to std-proposals+unsubscribe@isocpp.org <mailto:std-proposals+unsubs=
cribe@isocpp.org>.
> To post to this group, send email to std-proposals@isocpp.org <mailto:std=
-proposals@isocpp.org>.
> Visit this group at http://groups.google.com/a/isocpp.org/group/std-propo=
sals/ <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/.

--Apple-Mail=_7D505FFE-E753-4ABF-BFD4-C43E9EEACDA4
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On Aug 4, 2015, at 0=
1:05, Arthur O'Dwyer &lt;<a href=3D"mailto:arthur.j.odwyer@gmail.com" class=
=3D"">arthur.j.odwyer@gmail.com</a>&gt; wrote:</div><br class=3D"Apple-inte=
rchange-newline"><div class=3D""><div dir=3D"ltr" class=3D"">On Tue, Aug 4,=
 2015 at 12:32 AM, Roland Bock <span dir=3D"ltr" class=3D"">&lt;<a href=3D"=
mailto:rbock@eudoxos.de" target=3D"_blank" class=3D"">rbock@eudoxos.de</a>&=
gt;</span> wrote:<br class=3D""><div class=3D"gmail_extra"><div class=3D"gm=
ail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bor=
der-left:1px #ccc solid;padding-left:1ex">
 =20
   =20
 =20
  <div bgcolor=3D"#FFFFFF" text=3D"#000000" class=3D""><span class=3D"">
    <div class=3D"">On 2015-08-04 08:55, Arthur O'Dwyer
      wrote:<br class=3D"">
    </div>
    <blockquote type=3D"cite" class=3D"">
      <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" class=3D"">
          <div class=3D"gmail_extra">
            <div class=3D"gmail_quote">
              <div class=3D"">using Void =3D void;<br class=3D"">
              </div>
              <div class=3D""><br class=3D"">
              </div>
              <div class=3D"">void foo() {} &nbsp;// foo0</div>
              <div class=3D"">void foo(Void) {} // foo1</div>
            </div>
          </div>
        </div>
      </blockquote>
      <div class=3D""><br class=3D"">
      </div>
      <div class=3D"">In my world this is a violation of the ODR; foo0 and =
foo1 are
        the same function.</div>
    </blockquote></span>
    Being aware that this is currently the case I wonder if it is a good
    idea?<br class=3D"">
    <br class=3D"">
    If we could have values of type void, then I doubt that the above
    makes sense?<br class=3D""></div></blockquote><div class=3D"">[...]&nbs=
p;</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border=
-left:1px #ccc solid;padding-left:1ex"><div bgcolor=3D"#FFFFFF" text=3D"#00=
0000" class=3D"">We could however introduce a new thing, e.g. std::none, th=
at could
    be designed from afresh and have all the nice features we would like
    to see in void.<br class=3D""></div></blockquote><div class=3D""><br cl=
ass=3D""></div><div class=3D"">Sounds like <font face=3D"monospace, monospa=
ce" class=3D"">std::nullptr_t</font> is already <i class=3D"">that</i> thin=
g: it's new, it's unitary, it provides relational operators. If you just wa=
nt something that behaves like Python's <font face=3D"monospace, monospace"=
 class=3D"">None</font>, nullptr fits the bill exactly.</div></div></div></=
div></div></blockquote><div><br class=3D""></div><div>The issue there is th=
at is that nullptr is convertible to lots of things (T*) and not to a many =
others (T). That makes it an odd universal void type.</div><div><br class=
=3D""></div><blockquote type=3D"cite" class=3D""><div class=3D""><div dir=
=3D"ltr" class=3D""><div class=3D"gmail_extra"><div class=3D"gmail_quote"><=
div class=3D""><br class=3D""></div><div class=3D"">Another new-in-C++11, u=
nitary, regular type in the standard library is <font face=3D"monospace, mo=
nospace" class=3D"">std::tuple&lt;&gt;</font> (that is, a tuple of zero ele=
ments).</div><div class=3D""><br class=3D""></div><div class=3D"">But the p=
roblem is generic programming that needs to work with void parameter types =
(a.k.a. nullary functions) and void return types =E2=80=94 not <font face=
=3D"monospace, monospace" class=3D"">nullptr_t</font>, not <font face=3D"mo=
nospace, monospace" class=3D"">std::tuple&lt;&gt;</font>, but literally and=
 exactly&nbsp;<font face=3D"monospace, monospace" class=3D"">void</font>. I=
nventing new types almost certainly won't solve the problem, because the pr=
oblem specifically concerns&nbsp;<font face=3D"monospace, monospace" class=
=3D"">void</font>.</div></div></div></div></div></blockquote><div><br class=
=3D""></div><div>Maybe there should be a new special type defined as declty=
pe(void), which is convertible to and from places where =E2=80=98void=E2=80=
=99 currently exists, but is also a regular type. It can be a =E2=80=9Ccond=
uit=E2=80=9D type to make void things regular, but give you an escape hatch=
 back to =E2=80=98void=E2=80=99 when it=E2=80=99s needed.</div><div><br cla=
ss=3D""></div><div>auto v =3D foo(); &nbsp; // type is =E2=80=98decltype(vo=
id)=E2=80=99</div><div>return v; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;/=
/ =E2=80=98decltype(void)=E2=80=99 is convertible to void return type</div>=
<div><br class=3D""></div><div>We define a name under namespace std that is=
 defined to be that type (like nullptr_t does).</div><div><br class=3D""></=
div><div class=3D""><br class=3D""></div><blockquote type=3D"cite" class=3D=
""><div class=3D""><div dir=3D"ltr" class=3D""><div class=3D"gmail_extra"><=
div class=3D"gmail_quote"><div class=3D""><br class=3D""></div><div class=
=3D"">=E2=80=93Arthur</div></div></div></div><div class=3D""><br class=3D"w=
ebkit-block-placeholder"></div>

-- <br class=3D"">
<br class=3D"">
--- <br class=3D"">
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.<br class=3D"">
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" class=3D"">=
std-proposals+unsubscribe@isocpp.org</a>.<br class=3D"">
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" class=3D"">std-proposals@isocpp.org</a>.<br class=3D"">
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" class=3D"">http://groups.google.com/a/isocpp.org/group/std-=
proposals/</a>.<br class=3D"">
</div></blockquote></div><br class=3D""></body></html>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_7D505FFE-E753-4ABF-BFD4-C43E9EEACDA4--

.


Author: Zach Laine <whatwasthataddress@gmail.com>
Date: Tue, 4 Aug 2015 10:13:04 -0500
Raw View
--047d7ba97d420ec0ed051c7db9b9
Content-Type: text/plain; charset=UTF-8

On Tue, Aug 4, 2015 at 9:57 AM, Paul Fultz II <pfultz28@gmail.com> wrote:

>
> On Tuesday, August 4, 2015 at 4:00:41 AM UTC-5, Bengt Gustafsson wrote:
>>
>> How about just defining that void behaves like an empty struct? This
>> avoids us having to discuss every particular case. There are still the
>> potentials for code breakage with tricky SFINAE but I don't see how that
>> can ever be avoided if we change the behaviour of void at all. Note: I
>> don't mean that void should BE an empty struct in that you can inherit from
>> it, but that it acts like one when used in code.
>>
>
> But having void act like an empty struct, then it becomes a type with one
> value. However, `void` should mean a type with zero values(like a function
> that doesn't return anything). Of course, changing `void` from having zero
> values to one value could break a lot of assumptions made about code. I
> think its a bad idea. For some generic code, it may be safe to assume void
> as having one value instead of zero, but it would be better to use a
> library solution for this instead of baking in potential unsafe type
> assumptions into the language.
>

Again, I don't see the one value you mention.  Please point to the value
below:

struct foo
{
};

Where is it?  Objects of type "foo" have an address, but no value, right?
What am I missing?

Zach

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
ue, Aug 4, 2015 at 9:57 AM, Paul Fultz II <span dir=3D"ltr">&lt;<a href=3D"=
mailto:pfultz28@gmail.com" target=3D"_blank">pfultz28@gmail.com</a>&gt;</sp=
an> wrote:<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"><br>On Tuesda=
y, August 4, 2015 at 4:00:41 AM UTC-5, Bengt Gustafsson wrote:<blockquote c=
lass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #c=
cc solid;padding-left:1ex"><div dir=3D"ltr">How about just defining that vo=
id behaves like an empty struct? This avoids us having to discuss every par=
ticular case. There are still the potentials for code breakage with tricky =
SFINAE but I don&#39;t see how that can ever be avoided if we change the be=
haviour of void at all. Note: I don&#39;t mean that void should BE an empty=
 struct in that you can inherit from it, but that it acts like one when use=
d in code.<br></div></blockquote><div>=C2=A0<br>But having void act like an=
 empty struct, then it becomes a type with one value. However, `void` shoul=
d mean a type with zero values(like a function that doesn&#39;t return anyt=
hing). Of course, changing `void` from having zero values to one value coul=
d break a lot of assumptions made about code. I think its a bad idea. For s=
ome generic code, it may be safe to assume void as having one value instead=
 of zero, but it would be better to use a library solution for this instead=
 of baking in potential unsafe type assumptions into the language.</div></d=
iv></blockquote><div><br></div><div>Again, I don&#39;t see the one value yo=
u mention.=C2=A0 Please point to the value below:</div><div><br></div><div>=
struct foo</div><div>{</div><div>};</div><div><br></div><div>Where is it?=
=C2=A0 Objects of type &quot;foo&quot; have an address, but no value, right=
?=C2=A0 What am I missing?=C2=A0</div></div><br></div><div class=3D"gmail_e=
xtra">Zach</div><div class=3D"gmail_extra"><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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--047d7ba97d420ec0ed051c7db9b9--

.


Author: "'Edward Catmur' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Tue, 4 Aug 2015 16:15:47 +0100
Raw View
--047d7bb04272bfd849051c7dc243
Content-Type: text/plain; charset=UTF-8

Here is the value:

    foo{}

Compare to [basic.fundamental]:

> [...] 9 - The void type has an empty set of values. [...]

An expression of type void *does not have a value*.

On Tue, Aug 4, 2015 at 4:13 PM, Zach Laine <whatwasthataddress@gmail.com>
wrote:

> On Tue, Aug 4, 2015 at 9:57 AM, Paul Fultz II <pfultz28@gmail.com> wrote:
>
>>
>> On Tuesday, August 4, 2015 at 4:00:41 AM UTC-5, Bengt Gustafsson wrote:
>>>
>>> How about just defining that void behaves like an empty struct? This
>>> avoids us having to discuss every particular case. There are still the
>>> potentials for code breakage with tricky SFINAE but I don't see how that
>>> can ever be avoided if we change the behaviour of void at all. Note: I
>>> don't mean that void should BE an empty struct in that you can inherit from
>>> it, but that it acts like one when used in code.
>>>
>>
>> But having void act like an empty struct, then it becomes a type with one
>> value. However, `void` should mean a type with zero values(like a function
>> that doesn't return anything). Of course, changing `void` from having zero
>> values to one value could break a lot of assumptions made about code. I
>> think its a bad idea. For some generic code, it may be safe to assume void
>> as having one value instead of zero, but it would be better to use a
>> library solution for this instead of baking in potential unsafe type
>> assumptions into the language.
>>
>
> Again, I don't see the one value you mention.  Please point to the value
> below:
>
> struct foo
> {
> };
>
> Where is it?  Objects of type "foo" have an address, but no value, right?
> What am I missing?
>
> Zach
>
> --
>
> ---
> You received this message because you are subscribed to a topic in the
> Google Groups "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/a/isocpp.org/d/topic/std-proposals/05prNzycvYU/unsubscribe
> .
> To unsubscribe from this group and all its topics, 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/.

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

<div dir=3D"ltr">Here is the value:<div><br></div><div>=C2=A0 =C2=A0 foo{}<=
/div><div><br></div><div>Compare to=C2=A0[basic.fundamental]:</div><div><br=
></div><div>&gt; [...] 9 - The void type has an empty set of values. [...]<=
br></div><div><br></div><div>An expression of type void *does not have a va=
lue*.</div></div><div class=3D"gmail_extra"><br><div class=3D"gmail_quote">=
On Tue, Aug 4, 2015 at 4:13 PM, Zach Laine <span dir=3D"ltr">&lt;<a href=3D=
"mailto:whatwasthataddress@gmail.com" target=3D"_blank">whatwasthataddress@=
gmail.com</a>&gt;</span> wrote:<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"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><span class=
=3D"">On Tue, Aug 4, 2015 at 9:57 AM, Paul Fultz II <span dir=3D"ltr">&lt;<=
a href=3D"mailto:pfultz28@gmail.com" target=3D"_blank">pfultz28@gmail.com</=
a>&gt;</span> wrote:<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"><br=
>On Tuesday, August 4, 2015 at 4:00:41 AM UTC-5, Bengt Gustafsson wrote:<bl=
ockquote 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">How about just defini=
ng that void behaves like an empty struct? This avoids us having to discuss=
 every particular case. There are still the potentials for code breakage wi=
th tricky SFINAE but I don&#39;t see how that can ever be avoided if we cha=
nge the behaviour of void at all. Note: I don&#39;t mean that void should B=
E an empty struct in that you can inherit from it, but that it acts like on=
e when used in code.<br></div></blockquote><div>=C2=A0<br>But having void a=
ct like an empty struct, then it becomes a type with one value. However, `v=
oid` should mean a type with zero values(like a function that doesn&#39;t r=
eturn anything). Of course, changing `void` from having zero values to one =
value could break a lot of assumptions made about code. I think its a bad i=
dea. For some generic code, it may be safe to assume void as having one val=
ue instead of zero, but it would be better to use a library solution for th=
is instead of baking in potential unsafe type assumptions into the language=
..</div></div></blockquote><div><br></div></span><div>Again, I don&#39;t see=
 the one value you mention.=C2=A0 Please point to the value below:</div><di=
v><br></div><div>struct foo</div><div>{</div><div>};</div><div><br></div><d=
iv>Where is it?=C2=A0 Objects of type &quot;foo&quot; have an address, but =
no value, right?=C2=A0 What am I missing?=C2=A0</div></div><span class=3D"H=
OEnZb"><font color=3D"#888888"><br></font></span></div><span class=3D"HOEnZ=
b"><font color=3D"#888888"><div class=3D"gmail_extra">Zach</div><div class=
=3D"gmail_extra"><br></div></font></span></div><div class=3D"HOEnZb"><div c=
lass=3D"h5">

<p></p>

-- <br>
<br>
--- <br>
You received this message because you are subscribed to a topic in the Goog=
le Groups &quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this topic, visit <a href=3D"https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/05prNzycvYU/unsubscribe" target=3D"_blan=
k">https://groups.google.com/a/isocpp.org/d/topic/std-proposals/05prNzycvYU=
/unsubscribe</a>.<br>
To unsubscribe from this group and all its topics, send an email to <a href=
=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_blank">std-prop=
osals+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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--047d7bb04272bfd849051c7dc243--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Tue, 04 Aug 2015 08:24:52 -0700
Raw View
On Tuesday 04 August 2015 10:13:04 Zach Laine wrote:
> Again, I don't see the one value you mention.  Please point to the value
> below:
>
> struct foo
> {
> };
>
> Where is it?  Objects of type "foo" have an address, but no value, right?
> What am I missing?

It took me some time to understand Matt's proposition too... there's a very
subtle difference between types with zero states and types with one state.

An empty struct, just like std::nullptr_t, can only assume one state. You can
say the state is "exists" or "created". Compare this to bool, which has two
states and a tristate which has, as its name says, three states.

A zero-state type requires a jump, a leap of faith. Remember when you were
sometime in early school and discussed zero: how can you have zero of
something? I don't remember the details of the discussion, but I remember
having discussions about it because it's non-obvious, like negative numbers
aren't obvious other.

Having zero of something is the same as not having. So an object with zero
states is the same as the object not existing. It does not even have an
address.
--
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/.

.


Author: Paul Fultz II <pfultz28@gmail.com>
Date: Tue, 4 Aug 2015 08:32:14 -0700 (PDT)
Raw View
------=_Part_1491_1907385994.1438702334758
Content-Type: multipart/alternative;
 boundary="----=_Part_1492_470566398.1438702334759"

------=_Part_1492_470566398.1438702334759
Content-Type: text/plain; charset=UTF-8



On Tuesday, August 4, 2015 at 10:13:07 AM UTC-5, Zach Laine wrote:
>
> On Tue, Aug 4, 2015 at 9:57 AM, Paul Fultz II <pful...@gmail.com
> <javascript:>> wrote:
>
>>
>> On Tuesday, August 4, 2015 at 4:00:41 AM UTC-5, Bengt Gustafsson wrote:
>>>
>>> How about just defining that void behaves like an empty struct? This
>>> avoids us having to discuss every particular case. There are still the
>>> potentials for code breakage with tricky SFINAE but I don't see how that
>>> can ever be avoided if we change the behaviour of void at all. Note: I
>>> don't mean that void should BE an empty struct in that you can inherit from
>>> it, but that it acts like one when used in code.
>>>
>>
>> But having void act like an empty struct, then it becomes a type with one
>> value. However, `void` should mean a type with zero values(like a function
>> that doesn't return anything). Of course, changing `void` from having zero
>> values to one value could break a lot of assumptions made about code. I
>> think its a bad idea. For some generic code, it may be safe to assume void
>> as having one value instead of zero, but it would be better to use a
>> library solution for this instead of baking in potential unsafe type
>> assumptions into the language.
>>
>
> Again, I don't see the one value you mention.  Please point to the value
> below:
>
> struct foo
> {
> };
>
> Where is it?  Objects of type "foo" have an address, but no value, right?
> What am I missing?
>


Its `foo()`. Thats the one value. You can assign it to a variable:

auto x = foo();

So what value does `x` have? It has to have a value, and it is `foo()`.
Futhermore, you can return its value from a function:

foo f()
{ return foo(); }

If `foo` didn't have a value, then we wouldn't be able to return it from a
function. Also, you can observe that the values start to add up when we
start to sum them using a variant. How many values does `foo` have now?

struct empty1 {};
struct empty2 {};

typedef variant<empty1, empty2> foo;

It has two: `empty1()` and `empty2()`.



>
> Zach
>
>

--

---
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_1492_470566398.1438702334759
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<br><br>On Tuesday, August 4, 2015 at 10:13:07 AM UTC-5, Zach Laine wrote:<=
blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bord=
er-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div clas=
s=3D"gmail_quote">On Tue, Aug 4, 2015 at 9:57 AM, Paul Fultz II <span dir=
=3D"ltr">&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailt=
o=3D"HzaQM57oDwAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascr=
ipt:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return=
 true;">pful...@gmail.com</a>&gt;</span> wrote:<br><blockquote class=3D"gma=
il_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-lef=
t:1ex"><div dir=3D"ltr"><br>On Tuesday, August 4, 2015 at 4:00:41 AM UTC-5,=
 Bengt Gustafsson 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">How about just defining that void behaves like an empty struct? This =
avoids us having to discuss every particular case. There are still the pote=
ntials for code breakage with tricky SFINAE but I don&#39;t see how that ca=
n ever be avoided if we change the behaviour of void at all. Note: I don&#3=
9;t mean that void should BE an empty struct in that you can inherit from i=
t, but that it acts like one when used in code.<br></div></blockquote><div>=
=C2=A0<br>But having void act like an empty struct, then it becomes a type =
with one value. However, `void` should mean a type with zero values(like a =
function that doesn&#39;t return anything). Of course, changing `void` from=
 having zero values to one value could break a lot of assumptions made abou=
t code. I think its a bad idea. For some generic code, it may be safe to as=
sume void as having one value instead of zero, but it would be better to us=
e a library solution for this instead of baking in potential unsafe type as=
sumptions into the language.</div></div></blockquote><div><br></div><div>Ag=
ain, I don&#39;t see the one value you mention.=C2=A0 Please point to the v=
alue below:</div><div><br></div><div>struct foo</div><div>{</div><div>};</d=
iv><div><br></div><div>Where is it?=C2=A0 Objects of type &quot;foo&quot; h=
ave an address, but no value, right?=C2=A0 What am I missing?=C2=A0</div></=
div></div></div></blockquote><div><br><br>Its `foo()`. Thats the one value.=
 You can assign it to a variable:<br><br>auto x =3D foo();<br><br>So what v=
alue does `x` have? It has to have a value, and it is `foo()`. Futhermore, =
you can return its value from a function:<br><br>foo f()<br>{ return foo();=
 }<br><br>If `foo` didn&#39;t have a value, then we wouldn&#39;t be able to=
 return it from a function. Also, you can observe that the values start to =
add up when we start to sum them using a variant. How many values does `foo=
` have now?<br><br>struct empty1 {};<br>struct empty2 {};<br><br>typedef va=
riant&lt;empty1, empty2&gt; foo;<br><br>It has two: `empty1()` and `empty2(=
)`. <br><br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div d=
ir=3D"ltr"><div><br></div><div>Zach</div><div><br></div></div>
</blockquote>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_1492_470566398.1438702334759--
------=_Part_1491_1907385994.1438702334758--

.


Author: Zach Laine <whatwasthataddress@gmail.com>
Date: Tue, 4 Aug 2015 10:36:03 -0500
Raw View
--047d7bfd01b43e7682051c7e0b10
Content-Type: text/plain; charset=UTF-8

On Tue, Aug 4, 2015 at 10:24 AM, Thiago Macieira <thiago@macieira.org>
wrote:

> On Tuesday 04 August 2015 10:13:04 Zach Laine wrote:
> > Again, I don't see the one value you mention.  Please point to the value
> > below:
> >
> > struct foo
> > {
> > };
> >
> > Where is it?  Objects of type "foo" have an address, but no value, right?
> > What am I missing?
>
> It took me some time to understand Matt's proposition too... there's a very
> subtle difference between types with zero states and types with one state.
>
> An empty struct, just like std::nullptr_t, can only assume one state. You
> can
> say the state is "exists" or "created". Compare this to bool, which has two
> states and a tristate which has, as its name says, three states.
>
> A zero-state type requires a jump, a leap of faith. Remember when you were
> sometime in early school and discussed zero: how can you have zero of
> something? I don't remember the details of the discussion, but I remember
> having discussions about it because it's non-obvious, like negative numbers
> aren't obvious other.
>
> Having zero of something is the same as not having. So an object with zero
> states is the same as the object not existing. It does not even have an
> address.
>

I'm a bit confused by your response.  IFAICT, Matt is suggesting that void
behave as if it were defined as struct void{}.  Right?

Zach

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
ue, Aug 4, 2015 at 10:24 AM, Thiago Macieira <span dir=3D"ltr">&lt;<a href=
=3D"mailto:thiago@macieira.org" target=3D"_blank">thiago@macieira.org</a>&g=
t;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0=
 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=3D"">On Tues=
day 04 August 2015 10:13:04 Zach Laine wrote:<br>
&gt; Again, I don&#39;t see the one value you mention.=C2=A0 Please point t=
o the value<br>
&gt; below:<br>
&gt;<br>
&gt; struct foo<br>
&gt; {<br>
&gt; };<br>
&gt;<br>
&gt; Where is it?=C2=A0 Objects of type &quot;foo&quot; have an address, bu=
t no value, right?<br>
&gt; What am I missing?<br>
<br>
</span>It took me some time to understand Matt&#39;s proposition too... the=
re&#39;s a very<br>
subtle difference between types with zero states and types with one state.<=
br>
<br>
An empty struct, just like std::nullptr_t, can only assume one state. You c=
an<br>
say the state is &quot;exists&quot; or &quot;created&quot;. Compare this to=
 bool, which has two<br>
states and a tristate which has, as its name says, three states.<br>
<br>
A zero-state type requires a jump, a leap of faith. Remember when you were<=
br>
sometime in early school and discussed zero: how can you have zero of<br>
something? I don&#39;t remember the details of the discussion, but I rememb=
er<br>
having discussions about it because it&#39;s non-obvious, like negative num=
bers<br>
aren&#39;t obvious other.<br>
<br>
Having zero of something is the same as not having. So an object with zero<=
br>
states is the same as the object not existing. It does not even have an<br>
address.<br></blockquote><div><br></div><div>I&#39;m a bit confused by your=
 response.=C2=A0 IFAICT, Matt is suggesting that void behave as if it were =
defined as struct void{}.=C2=A0 Right?</div><div><br></div><div>Zach</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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--047d7bfd01b43e7682051c7e0b10--

.


Author: Zach Laine <whatwasthataddress@gmail.com>
Date: Tue, 4 Aug 2015 10:41:05 -0500
Raw View
--047d7bfd01b4451386051c7e1d7f
Content-Type: text/plain; charset=UTF-8

On Tue, Aug 4, 2015 at 10:32 AM, Paul Fultz II <pfultz28@gmail.com> wrote:

>
>
> On Tuesday, August 4, 2015 at 10:13:07 AM UTC-5, Zach Laine wrote:
>>
>> On Tue, Aug 4, 2015 at 9:57 AM, Paul Fultz II <pful...@gmail.com> wrote:
>>
>>>
>>> On Tuesday, August 4, 2015 at 4:00:41 AM UTC-5, Bengt Gustafsson wrote:
>>>>
>>>> How about just defining that void behaves like an empty struct? This
>>>> avoids us having to discuss every particular case. There are still the
>>>> potentials for code breakage with tricky SFINAE but I don't see how that
>>>> can ever be avoided if we change the behaviour of void at all. Note: I
>>>> don't mean that void should BE an empty struct in that you can inherit from
>>>> it, but that it acts like one when used in code.
>>>>
>>>
>>> But having void act like an empty struct, then it becomes a type with
>>> one value. However, `void` should mean a type with zero values(like a
>>> function that doesn't return anything). Of course, changing `void` from
>>> having zero values to one value could break a lot of assumptions made about
>>> code. I think its a bad idea. For some generic code, it may be safe to
>>> assume void as having one value instead of zero, but it would be better to
>>> use a library solution for this instead of baking in potential unsafe type
>>> assumptions into the language.
>>>
>>
>> Again, I don't see the one value you mention.  Please point to the value
>> below:
>>
>> struct foo
>> {
>> };
>>
>> Where is it?  Objects of type "foo" have an address, but no value,
>> right?  What am I missing?
>>
>
>
> Its `foo()`. Thats the one value. You can assign it to a variable:
>
> auto x = foo();
>
> So what value does `x` have? It has to have a value, and it is `foo()`.
> Futhermore, you can return its value from a function:
>
> foo f()
> { return foo(); }
>
> If `foo` didn't have a value, then we wouldn't be able to return it from a
> function. Also, you can observe that the values start to add up when we
> start to sum them using a variant. How many values does `foo` have now?
>
> struct empty1 {};
> struct empty2 {};
>
> typedef variant<empty1, empty2> foo;
>
> It has two: `empty1()` and `empty2()`.
>

Please write an if statement predicated on the values of empty1() and
empty2() that takes different paths depending on runtime state, without
relying on UB.

My point is that there is no non-UB-invoking observable runtime state for
these objects.  They have no values that are meaningful to my program's
state.  They are meaningful at compile time only.

Zach

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
ue, Aug 4, 2015 at 10:32 AM, Paul Fultz II <span dir=3D"ltr">&lt;<a href=3D=
"mailto:pfultz28@gmail.com" target=3D"_blank">pfultz28@gmail.com</a>&gt;</s=
pan> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex=
;border-left:1px #ccc solid;padding-left:1ex"><br><br>On Tuesday, August 4,=
 2015 at 10:13:07 AM UTC-5, Zach Laine wrote:<span class=3D""><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #c=
cc solid;padding-left:1ex"><div dir=3D"ltr"><div><div class=3D"gmail_quote"=
>On Tue, Aug 4, 2015 at 9:57 AM, Paul Fultz II <span dir=3D"ltr">&lt;<a rel=
=3D"nofollow">pful...@gmail.com</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"><div dir=3D"ltr"><br>On Tuesday, August 4, 2015 at 4:00:41 AM=
 UTC-5, Bengt Gustafsson wrote:<blockquote class=3D"gmail_quote" style=3D"m=
argin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div=
 dir=3D"ltr">How about just defining that void behaves like an empty struct=
? This avoids us having to discuss every particular case. There are still t=
he potentials for code breakage with tricky SFINAE but I don&#39;t see how =
that can ever be avoided if we change the behaviour of void at all. Note: I=
 don&#39;t mean that void should BE an empty struct in that you can inherit=
 from it, but that it acts like one when used in code.<br></div></blockquot=
e><div>=C2=A0<br>But having void act like an empty struct, then it becomes =
a type with one value. However, `void` should mean a type with zero values(=
like a function that doesn&#39;t return anything). Of course, changing `voi=
d` from having zero values to one value could break a lot of assumptions ma=
de about code. I think its a bad idea. For some generic code, it may be saf=
e to assume void as having one value instead of zero, but it would be bette=
r to use a library solution for this instead of baking in potential unsafe =
type assumptions into the language.</div></div></blockquote><div><br></div>=
<div>Again, I don&#39;t see the one value you mention.=C2=A0 Please point t=
o the value below:</div><div><br></div><div>struct foo</div><div>{</div><di=
v>};</div><div><br></div><div>Where is it?=C2=A0 Objects of type &quot;foo&=
quot; have an address, but no value, right?=C2=A0 What am I missing?=C2=A0<=
/div></div></div></div></blockquote></span><div><br><br>Its `foo()`. Thats =
the one value. You can assign it to a variable:<br><br>auto x =3D foo();<br=
><br>So what value does `x` have? It has to have a value, and it is `foo()`=
.. Futhermore, you can return its value from a function:<br><br>foo f()<br>{=
 return foo(); }<br><br>If `foo` didn&#39;t have a value, then we wouldn&#3=
9;t be able to return it from a function. Also, you can observe that the va=
lues start to add up when we start to sum them using a variant. How many va=
lues does `foo` have now?<br><br>struct empty1 {};<br>struct empty2 {};<br>=
<br>typedef variant&lt;empty1, empty2&gt; foo;<br><br>It has two: `empty1()=
` and `empty2()`. <br></div></blockquote><div><br></div><div>Please write a=
n if statement predicated on the values of empty1() and empty2() that takes=
 different paths depending on runtime state, without relying on UB.</div><d=
iv><br></div><div>My point is that there is no non-UB-invoking observable r=
untime state for these objects.=C2=A0 They have no values that are meaningf=
ul to my program&#39;s state.=C2=A0 They are meaningful at compile time onl=
y.</div><div><br></div><div>Zach</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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--047d7bfd01b4451386051c7e1d7f--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Tue, 04 Aug 2015 08:41:44 -0700
Raw View
On Tuesday 04 August 2015 10:36:03 Zach Laine wrote:
> I'm a bit confused by your response.  IFAICT, Matt is suggesting that void
> behave as if it were defined as struct void{}.  Right?

I thought he was, until the discussion on std::tuple<int, void, int>.
--
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/.

.


Author: Paul Fultz II <pfultz28@gmail.com>
Date: Tue, 4 Aug 2015 09:14:04 -0700 (PDT)
Raw View
------=_Part_227_133279618.1438704844940
Content-Type: multipart/alternative;
 boundary="----=_Part_228_167993887.1438704844940"

------=_Part_228_167993887.1438704844940
Content-Type: text/plain; charset=UTF-8



On Tuesday, August 4, 2015 at 10:41:08 AM UTC-5, Zach Laine wrote:
>
> On Tue, Aug 4, 2015 at 10:32 AM, Paul Fultz II <pful...@gmail.com
> <javascript:>> wrote:
>
>>
>>
>> On Tuesday, August 4, 2015 at 10:13:07 AM UTC-5, Zach Laine wrote:
>>>
>>> On Tue, Aug 4, 2015 at 9:57 AM, Paul Fultz II <pful...@gmail.com> wrote:
>>>
>>>>
>>>> On Tuesday, August 4, 2015 at 4:00:41 AM UTC-5, Bengt Gustafsson wrote:
>>>>>
>>>>> How about just defining that void behaves like an empty struct? This
>>>>> avoids us having to discuss every particular case. There are still the
>>>>> potentials for code breakage with tricky SFINAE but I don't see how that
>>>>> can ever be avoided if we change the behaviour of void at all. Note: I
>>>>> don't mean that void should BE an empty struct in that you can inherit from
>>>>> it, but that it acts like one when used in code.
>>>>>
>>>>
>>>> But having void act like an empty struct, then it becomes a type with
>>>> one value. However, `void` should mean a type with zero values(like a
>>>> function that doesn't return anything). Of course, changing `void` from
>>>> having zero values to one value could break a lot of assumptions made about
>>>> code. I think its a bad idea. For some generic code, it may be safe to
>>>> assume void as having one value instead of zero, but it would be better to
>>>> use a library solution for this instead of baking in potential unsafe type
>>>> assumptions into the language.
>>>>
>>>
>>> Again, I don't see the one value you mention.  Please point to the value
>>> below:
>>>
>>> struct foo
>>> {
>>> };
>>>
>>> Where is it?  Objects of type "foo" have an address, but no value,
>>> right?  What am I missing?
>>>
>>
>>
>> Its `foo()`. Thats the one value. You can assign it to a variable:
>>
>> auto x = foo();
>>
>> So what value does `x` have? It has to have a value, and it is `foo()`.
>> Futhermore, you can return its value from a function:
>>
>> foo f()
>> { return foo(); }
>>
>> If `foo` didn't have a value, then we wouldn't be able to return it from
>> a function. Also, you can observe that the values start to add up when we
>> start to sum them using a variant. How many values does `foo` have now?
>>
>> struct empty1 {};
>> struct empty2 {};
>>
>> typedef variant<empty1, empty2> foo;
>>
>> It has two: `empty1()` and `empty2()`.
>>
>
> Please write an if statement predicated on the values of empty1() and
> empty2() that takes different paths depending on runtime state, without
> relying on UB.
>

foo x = empty1();

if (x.which() == 0) std::cout << "empty1";
else std::cout << "empty2";

Thats not UB. As someone else suggested that `variant` have a templated
`has` method, you could write this:

if (x.has<empty1>()) std::cout << "empty1";
else std::cout << "empty2";

Same logic, just easier to read.



>
> My point is that there is no non-UB-invoking observable runtime state for
> these objects.  They have no values that are meaningful to my program's
> state.  They are meaningful at compile time only.
>

I am discussing runtime values,not compile time values. In fact, `foo` has
the same runtime values that a boolean has, with the addition of being able
to pattern match on its values. The fact that runtime values and compile
time values are the same is because it is dependently-typed.


>
> Zach
>

--

---
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_228_167993887.1438704844940
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<br><br>On Tuesday, August 4, 2015 at 10:41:08 AM UTC-5, Zach Laine wrote:<=
blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bord=
er-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div clas=
s=3D"gmail_quote">On Tue, Aug 4, 2015 at 10:32 AM, Paul Fultz II <span dir=
=3D"ltr">&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailt=
o=3D"cXbIyCXqDwAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascr=
ipt:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return=
 true;">pful...@gmail.com</a>&gt;</span> wrote:<br><blockquote class=3D"gma=
il_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-lef=
t:1ex"><br><br>On Tuesday, August 4, 2015 at 10:13:07 AM UTC-5, Zach Laine =
wrote:<span><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">On Tue, Aug 4, 2015 at 9:57 AM, Paul Fultz II <sp=
an dir=3D"ltr">&lt;<a rel=3D"nofollow">pful...@gmail.com</a>&gt;</span> wro=
te:<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"><br>On Tuesday, Augu=
st 4, 2015 at 4:00:41 AM UTC-5, Bengt Gustafsson wrote:<blockquote class=3D=
"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc soli=
d;padding-left:1ex"><div dir=3D"ltr">How about just defining that void beha=
ves like an empty struct? This avoids us having to discuss every particular=
 case. There are still the potentials for code breakage with tricky SFINAE =
but I don&#39;t see how that can ever be avoided if we change the behaviour=
 of void at all. Note: I don&#39;t mean that void should BE an empty struct=
 in that you can inherit from it, but that it acts like one when used in co=
de.<br></div></blockquote><div>=C2=A0<br>But having void act like an empty =
struct, then it becomes a type with one value. However, `void` should mean =
a type with zero values(like a function that doesn&#39;t return anything). =
Of course, changing `void` from having zero values to one value could break=
 a lot of assumptions made about code. I think its a bad idea. For some gen=
eric code, it may be safe to assume void as having one value instead of zer=
o, but it would be better to use a library solution for this instead of bak=
ing in potential unsafe type assumptions into the language.</div></div></bl=
ockquote><div><br></div><div>Again, I don&#39;t see the one value you menti=
on.=C2=A0 Please point to the value below:</div><div><br></div><div>struct =
foo</div><div>{</div><div>};</div><div><br></div><div>Where is it?=C2=A0 Ob=
jects of type &quot;foo&quot; have an address, but no value, right?=C2=A0 W=
hat am I missing?=C2=A0</div></div></div></div></blockquote></span><div><br=
><br>Its `foo()`. Thats the one value. You can assign it to a variable:<br>=
<br>auto x =3D foo();<br><br>So what value does `x` have? It has to have a =
value, and it is `foo()`. Futhermore, you can return its value from a funct=
ion:<br><br>foo f()<br>{ return foo(); }<br><br>If `foo` didn&#39;t have a =
value, then we wouldn&#39;t be able to return it from a function. Also, you=
 can observe that the values start to add up when we start to sum them usin=
g a variant. How many values does `foo` have now?<br><br>struct empty1 {};<=
br>struct empty2 {};<br><br>typedef variant&lt;empty1, empty2&gt; foo;<br><=
br>It has two: `empty1()` and `empty2()`. <br></div></blockquote><div><br><=
/div><div>Please write an if statement predicated on the values of empty1()=
 and empty2() that takes different paths depending on runtime state, withou=
t relying on UB.</div></div></div></div></blockquote><div><br>foo x =3D emp=
ty1();<br><br>if (x.which() =3D=3D 0) std::cout &lt;&lt; &quot;empty1&quot;=
;<br>else std::cout &lt;&lt; &quot;empty2&quot;;<br><br>Thats not UB. As so=
meone else suggested that `variant` have a templated `has` method, you coul=
d write this:<br><br>if (x.has&lt;empty1&gt;()) std::cout &lt;&lt; &quot;em=
pty1&quot;;<br>else std::cout &lt;&lt; &quot;empty2&quot;;<br><br>Same logi=
c, just easier to read.<br><br>=C2=A0</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><br></di=
v><div>My point is that there is no non-UB-invoking observable runtime stat=
e for these objects.=C2=A0 They have no values that are meaningful to my pr=
ogram&#39;s state.=C2=A0 They are meaningful at compile time only.</div></d=
iv></div></div></blockquote><div>=C2=A0</div><div>I am discussing runtime v=
alues,not compile time values. In fact, `foo` has the same runtime values t=
hat a boolean has, with the addition of being able to pattern match on its =
values. The fact that runtime values and compile time values are the same i=
s because it is dependently-typed.<br>=C2=A0<br></div><blockquote class=3D"=
gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc so=
lid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><d=
iv><br></div><div>Zach</div></div></div></div>
</blockquote>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_228_167993887.1438704844940--
------=_Part_227_133279618.1438704844940--

.


Author: "'Johannes Schaub' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Tue, 4 Aug 2015 18:37:40 +0200
Raw View
--001a113f97d8a10c06051c7ee798
Content-Type: text/plain; charset=UTF-8

Am 04.08.2015 17:15 schrieb "'Edward Catmur' via ISO C++ Standard - Future
Proposals" <std-proposals@isocpp.org>:
>
> Here is the value:
>
>     foo{}
>
> Compare to [basic.fundamental]:
>
> > [...] 9 - The void type has an empty set of values. [...]
>
> An expression of type void *does not have a value*.
>

While I agree, I must point out that there does not appear to be consensus
(even officially) on the definition of the term "value". While the spec has
a seemingly clear definition of it, with the introduction of the terms
"value computation" that can result in an object or function identity for
lvalues and in member function identity for rvalues, the term "value" has
been used by some in manners meaning "result meaning of expression
evaluation".

> On Tue, Aug 4, 2015 at 4:13 PM, Zach Laine <whatwasthataddress@gmail.com>
wrote:
>>
>> On Tue, Aug 4, 2015 at 9:57 AM, Paul Fultz II <pfultz28@gmail.com> wrote:
>>>
>>>
>>> On Tuesday, August 4, 2015 at 4:00:41 AM UTC-5, Bengt Gustafsson wrote:
>>>>
>>>> How about just defining that void behaves like an empty struct? This
avoids us having to discuss every particular case. There are still the
potentials for code breakage with tricky SFINAE but I don't see how that
can ever be avoided if we change the behaviour of void at all. Note: I
don't mean that void should BE an empty struct in that you can inherit from
it, but that it acts like one when used in code.
>>>
>>>
>>> But having void act like an empty struct, then it becomes a type with
one value. However, `void` should mean a type with zero values(like a
function that doesn't return anything). Of course, changing `void` from
having zero values to one value could break a lot of assumptions made about
code. I think its a bad idea. For some generic code, it may be safe to
assume void as having one value instead of zero, but it would be better to
use a library solution for this instead of baking in potential unsafe type
assumptions into the language.
>>
>>
>> Again, I don't see the one value you mention.  Please point to the value
below:
>>
>> struct foo
>> {
>> };
>>
>> Where is it?  Objects of type "foo" have an address, but no value,
right?  What am I missing?
>>
>> Zach
>>
>> --
>>
>> ---
>> You received this message because you are subscribed to a topic in the
Google Groups "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this topic, visit
https://groups.google.com/a/isocpp.org/d/topic/std-proposals/05prNzycvYU/unsubscribe
..
>> To unsubscribe from this group and all its topics, 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/.

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

<p dir=3D"ltr"><br>
Am 04.08.2015 17:15 schrieb &quot;&#39;Edward Catmur&#39; via ISO C++ Stand=
ard - Future Proposals&quot; &lt;<a href=3D"mailto:std-proposals@isocpp.org=
">std-proposals@isocpp.org</a>&gt;:<br>
&gt;<br>
&gt; Here is the value:<br>
&gt;<br>
&gt; =C2=A0 =C2=A0 foo{}<br>
&gt;<br>
&gt; Compare to=C2=A0[basic.fundamental]:<br>
&gt;<br>
&gt; &gt; [...] 9 - The void type has an empty set of values. [...]<br>
&gt;<br>
&gt; An expression of type void *does not have a value*.<br>
&gt;</p>
<p dir=3D"ltr">While I agree, I must point out that there does not appear t=
o be consensus (even officially) on the definition of the term &quot;value&=
quot;. While the spec has a seemingly clear definition of it, with the intr=
oduction of the terms &quot;value computation&quot; that can result in an o=
bject or function identity for lvalues and in member function identity for =
rvalues, the term &quot;value&quot; has been used by some in manners meanin=
g &quot;result meaning of expression evaluation&quot;. </p>
<p dir=3D"ltr">&gt; On Tue, Aug 4, 2015 at 4:13 PM, Zach Laine &lt;<a href=
=3D"mailto:whatwasthataddress@gmail.com">whatwasthataddress@gmail.com</a>&g=
t; wrote:<br>
&gt;&gt;<br>
&gt;&gt; On Tue, Aug 4, 2015 at 9:57 AM, Paul Fultz II &lt;<a href=3D"mailt=
o:pfultz28@gmail.com">pfultz28@gmail.com</a>&gt; wrote:<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; On Tuesday, August 4, 2015 at 4:00:41 AM UTC-5, Bengt Gustafss=
on wrote:<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; How about just defining that void behaves like an empty st=
ruct? This avoids us having to discuss every particular case. There are sti=
ll the potentials for code breakage with tricky SFINAE but I don&#39;t see =
how that can ever be avoided if we change the behaviour of void at all. Not=
e: I don&#39;t mean that void should BE an empty struct in that you can inh=
erit from it, but that it acts like one when used in code.<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; =C2=A0<br>
&gt;&gt;&gt; But having void act like an empty struct, then it becomes a ty=
pe with one value. However, `void` should mean a type with zero values(like=
 a function that doesn&#39;t return anything). Of course, changing `void` f=
rom having zero values to one value could break a lot of assumptions made a=
bout code. I think its a bad idea. For some generic code, it may be safe to=
 assume void as having one value instead of zero, but it would be better to=
 use a library solution for this instead of baking in potential unsafe type=
 assumptions into the language.<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; Again, I don&#39;t see the one value you mention.=C2=A0 Please poi=
nt to the value below:<br>
&gt;&gt;<br>
&gt;&gt; struct foo<br>
&gt;&gt; {<br>
&gt;&gt; };<br>
&gt;&gt;<br>
&gt;&gt; Where is it?=C2=A0 Objects of type &quot;foo&quot; have an address=
, but no value, right?=C2=A0 What am I missing?=C2=A0<br>
&gt;&gt;<br>
&gt;&gt; Zach<br>
&gt;&gt;<br>
&gt;&gt; -- <br>
&gt;&gt;<br>
&gt;&gt; --- <br>
&gt;&gt; You received this message because you are subscribed to a topic in=
 the Google Groups &quot;ISO C++ Standard - Future Proposals&quot; group.<b=
r>
&gt;&gt; To unsubscribe from this topic, visit <a href=3D"https://groups.go=
ogle.com/a/isocpp.org/d/topic/std-proposals/05prNzycvYU/unsubscribe">https:=
//groups.google.com/a/isocpp.org/d/topic/std-proposals/05prNzycvYU/unsubscr=
ibe</a>.<br>
&gt;&gt; To unsubscribe from this group and all its topics, send an email t=
o <a href=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org">std-proposals+u=
nsubscribe@isocpp.org</a>.<br>
&gt;&gt;<br>
&gt;&gt; To post to this group, send email to <a href=3D"mailto:std-proposa=
ls@isocpp.org">std-proposals@isocpp.org</a>.<br>
&gt;&gt; Visit this group at <a href=3D"http://groups.google.com/a/isocpp.o=
rg/group/std-proposals/">http://groups.google.com/a/isocpp.org/group/std-pr=
oposals/</a>.<br>
&gt;<br>
&gt;<br>
&gt; -- <br>
&gt;<br>
&gt; --- <br>
&gt; You received this message because you are subscribed to the Google Gro=
ups &quot;ISO C++ Standard - Future Proposals&quot; group.<br>
&gt; To unsubscribe from this group and stop receiving emails from it, send=
 an email to <a href=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org">std-=
proposals+unsubscribe@isocpp.org</a>.<br>
&gt; To post to this group, send email to <a href=3D"mailto:std-proposals@i=
socpp.org">std-proposals@isocpp.org</a>.<br>
&gt; Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/g=
roup/std-proposals/">http://groups.google.com/a/isocpp.org/group/std-propos=
als/</a>.<br>
</p>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a113f97d8a10c06051c7ee798--

.


Author: Zach Laine <whatwasthataddress@gmail.com>
Date: Tue, 4 Aug 2015 11:54:32 -0500
Raw View
--047d7ba97d42ee8cb5051c7f239c
Content-Type: text/plain; charset=UTF-8

On Tue, Aug 4, 2015 at 11:14 AM, Paul Fultz II <pfultz28@gmail.com> wrote:

>
>
> On Tuesday, August 4, 2015 at 10:41:08 AM UTC-5, Zach Laine wrote:
>>
>> On Tue, Aug 4, 2015 at 10:32 AM, Paul Fultz II <pful...@gmail.com> wrote:
>>
>>>
>>>
>>> Its `foo()`. Thats the one value. You can assign it to a variable:
>>>
>>> auto x = foo();
>>>
>>> So what value does `x` have? It has to have a value, and it is `foo()`.
>>> Futhermore, you can return its value from a function:
>>>
>>> foo f()
>>> { return foo(); }
>>>
>>> If `foo` didn't have a value, then we wouldn't be able to return it from
>>> a function. Also, you can observe that the values start to add up when we
>>> start to sum them using a variant. How many values does `foo` have now?
>>>
>>> struct empty1 {};
>>> struct empty2 {};
>>>
>>> typedef variant<empty1, empty2> foo;
>>>
>>> It has two: `empty1()` and `empty2()`.
>>>
>>
>> Please write an if statement predicated on the values of empty1() and
>> empty2() that takes different paths depending on runtime state, without
>> relying on UB.
>>
>
> foo x = empty1();
>
> if (x.which() == 0) std::cout << "empty1";
>

Stop right there.  You are using the value of the discriminator
"x.which()", which is an int with a runtime value.  You never used the
values of empty1() and empty2().

Zach

--

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

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

<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><div class=3D"gmail_quo=
te">On Tue, Aug 4, 2015 at 11:14 AM, Paul Fultz II <span dir=3D"ltr">&lt;<a=
 href=3D"mailto:pfultz28@gmail.com" target=3D"_blank">pfultz28@gmail.com</a=
>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 =
0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br><br>On Tuesday, A=
ugust 4, 2015 at 10:41:08 AM UTC-5, Zach Laine wrote:<span class=3D""><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-lef=
t:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><div class=3D"gmai=
l_quote">On Tue, Aug 4, 2015 at 10:32 AM, Paul Fultz II <span dir=3D"ltr">&=
lt;<a rel=3D"nofollow">pful...@gmail.com</a>&gt;</span> wrote:<br><blockquo=
te class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc so=
lid;padding-left:1ex"><br><br><div>Its `foo()`. Thats the one value. You ca=
n assign it to a variable:<br><br>auto x =3D foo();<br><br>So what value do=
es `x` have? It has to have a value, and it is `foo()`. Futhermore, you can=
 return its value from a function:<br><br>foo f()<br>{ return foo(); }<br><=
br>If `foo` didn&#39;t have a value, then we wouldn&#39;t be able to return=
 it from a function. Also, you can observe that the values start to add up =
when we start to sum them using a variant. How many values does `foo` have =
now?<br><br>struct empty1 {};<br>struct empty2 {};<br><br>typedef variant&l=
t;empty1, empty2&gt; foo;<br><br>It has two: `empty1()` and `empty2()`. <br=
></div></blockquote><div><br></div><div>Please write an if statement predic=
ated on the values of empty1() and empty2() that takes different paths depe=
nding on runtime state, without relying on UB.</div></div></div></div></blo=
ckquote></span><div><br>foo x =3D empty1();<br><br>if (x.which() =3D=3D 0) =
std::cout &lt;&lt; &quot;empty1&quot;;<br></div></blockquote><div><br></div=
><div>Stop right there.=C2=A0 You are using the value of the discriminator =
&quot;x.which()&quot;, which is an int with a runtime value.=C2=A0 You neve=
r used the values of empty1() and empty2().</div><div><br></div><div>Zach</=
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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--047d7ba97d42ee8cb5051c7f239c--

.


Author: Miro Knejp <miro.knejp@gmail.com>
Date: Tue, 4 Aug 2015 19:34:19 +0200
Raw View
--Apple-Mail=_C02DA706-8EA3-4C5C-8B9B-374DB7CAC6CE
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8


> On 04 Aug 2015, at 17:32 , Paul Fultz II <pfultz28@gmail.com> wrote:
>=20
>=20
>=20
> On Tuesday, August 4, 2015 at 10:13:07 AM UTC-5, Zach Laine wrote:
> On Tue, Aug 4, 2015 at 9:57 AM, Paul Fultz II <pful...@gmail.com <javascr=
ipt:>> wrote:
>=20
> On Tuesday, August 4, 2015 at 4:00:41 AM UTC-5, Bengt Gustafsson wrote:
> How about just defining that void behaves like an empty struct? This avoi=
ds us having to discuss every particular case. There are still the potentia=
ls for code breakage with tricky SFINAE but I don't see how that can ever b=
e avoided if we change the behaviour of void at all. Note: I don't mean tha=
t void should BE an empty struct in that you can inherit from it, but that =
it acts like one when used in code.
> =20
> But having void act like an empty struct, then it becomes a type with one=
 value. However, `void` should mean a type with zero values(like a function=
 that doesn't return anything). Of course, changing `void` from having zero=
 values to one value could break a lot of assumptions made about code. I th=
ink its a bad idea. For some generic code, it may be safe to assume void as=
 having one value instead of zero, but it would be better to use a library =
solution for this instead of baking in potential unsafe type assumptions in=
to the language.
>=20
> Again, I don't see the one value you mention.  Please point to the value =
below:
>=20
> struct foo
> {
> };
>=20
> Where is it?  Objects of type "foo" have an address, but no value, right?=
  What am I missing?=20
>=20
>=20
> Its `foo()`. Thats the one value. You can assign it to a variable:

Which is the very definition of a unit type. Technically they are indisting=
uishable. What changes that in C++ is the fact that we can assign every obj=
ect a memory address and therefore give every instance an *identity*. One c=
annot write a meaningful operator=3D=3D that can distinguish two foo operan=
ds without taking their address, but at that point we=E2=80=99re comparing =
identities, not states/values.

@Zach:
Regarding void: https://en.wikipedia.org/wiki/Unit_type#Void_type_as_unit_t=
ype <https://en.wikipedia.org/wiki/Unit_type#Void_type_as_unit_type>

--=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=_C02DA706-8EA3-4C5C-8B9B-374DB7CAC6CE
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 04 Aug 2015, at 1=
7:32 , Paul Fultz II &lt;<a href=3D"mailto:pfultz28@gmail.com" class=3D"">p=
fultz28@gmail.com</a>&gt; wrote:</div><br class=3D"Apple-interchange-newlin=
e"><div class=3D""><br class=3D""><br class=3D"">On Tuesday, August 4, 2015=
 at 10:13:07 AM UTC-5, Zach Laine wrote:<blockquote class=3D"gmail_quote" s=
tyle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-le=
ft: 1ex;"><div dir=3D"ltr" class=3D""><div class=3D""><div class=3D"gmail_q=
uote">On Tue, Aug 4, 2015 at 9:57 AM, Paul Fultz II <span dir=3D"ltr" class=
=3D"">&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=
=3D"HzaQM57oDwAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:'=
;return true;" onclick=3D"this.href=3D'javascript:';return true;" class=3D"=
">pful...@gmail.com</a>&gt;</span> wrote:<br class=3D""><blockquote class=
=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr" class=3D""><br class=3D"">On Tuesday, August=
 4, 2015 at 4:00:41 AM UTC-5, Bengt Gustafsson wrote:<blockquote class=3D"g=
mail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;=
padding-left:1ex"><div dir=3D"ltr" class=3D"">How about just defining that =
void behaves like an empty struct? This avoids us having to discuss every p=
articular case. There are still the potentials for code breakage with trick=
y SFINAE but I don't see how that can ever be avoided if we change the beha=
viour of void at all. Note: I don't mean that void should BE an empty struc=
t in that you can inherit from it, but that it acts like one when used in c=
ode.<br class=3D""></div></blockquote><div class=3D"">&nbsp;<br class=3D"">=
But having void act like an empty struct, then it becomes a type with one v=
alue. However, `void` should mean a type with zero values(like a function t=
hat doesn't return anything). Of course, changing `void` from having zero v=
alues to one value could break a lot of assumptions made about code. I thin=
k its a bad idea. For some generic code, it may be safe to assume void as h=
aving one value instead of zero, but it would be better to use a library so=
lution for this instead of baking in potential unsafe type assumptions into=
 the language.</div></div></blockquote><div class=3D""><br class=3D""></div=
><div class=3D"">Again, I don't see the one value you mention.&nbsp; Please=
 point to the value below:</div><div class=3D""><br class=3D""></div><div c=
lass=3D"">struct foo</div><div class=3D"">{</div><div class=3D"">};</div><d=
iv class=3D""><br class=3D""></div><div class=3D"">Where is it?&nbsp; Objec=
ts of type "foo" have an address, but no value, right?&nbsp; What am I miss=
ing?&nbsp;</div></div></div></div></blockquote><div class=3D""><br class=3D=
""><br class=3D"">Its `foo()`. Thats the one value. You can assign it to a =
variable:<br class=3D""></div></div></blockquote><div><br class=3D""></div>=
<div>Which is the very definition of a unit type. Technically they are indi=
stinguishable. What changes that in C++ is the fact that we can assign ever=
y object a memory address and therefore give every instance an *identity*. =
One cannot write a meaningful operator=3D=3D that can distinguish two foo o=
perands without taking their address, but at that point we=E2=80=99re compa=
ring identities, not states/values.</div><div><br class=3D""></div><div>@Za=
ch:</div><div>Regarding void:&nbsp;<a href=3D"https://en.wikipedia.org/wiki=
/Unit_type#Void_type_as_unit_type" class=3D"">https://en.wikipedia.org/wiki=
/Unit_type#Void_type_as_unit_type</a></div><div><br class=3D""></div></div>=
</body></html>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_C02DA706-8EA3-4C5C-8B9B-374DB7CAC6CE--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Tue, 4 Aug 2015 10:59:14 -0700
Raw View
--001a113cd18c5537e2051c800b9d
Content-Type: text/plain; charset=UTF-8

On Tue, Aug 4, 2015 at 8:24 AM, Thiago Macieira <thiago@macieira.org> wrote:

> On Tuesday 04 August 2015 10:13:04 Zach Laine wrote:
> > Again, I don't see the one value you mention.  Please point to the value
> > below:
> >
> > struct foo
> > {
> > };
> >
> > Where is it?  Objects of type "foo" have an address, but no value, right?
> > What am I missing?
>
> It took me some time to understand Matt's proposition too... there's a very
> subtle difference between types with zero states and types with one state.


In case there is any confusion, I DO mean struct void {}; I defined in C++
the type in a couple of replies in a hope that it would eliminate all
confusion. If "stateless" is the confusing part, for clarity, I'm referring
to the boost definition of stateless -- the docs have always had a standard
reference, though it now appears outdated. I didn't think there would be
confusion using this term in this forum. Quoting the docs:

//////////
A stateless type is a type that has no storage and whose constructors and
destructors are trivial. That means that is_stateless only inherits from
true_type if the following expression is true:

::boost::has_trivial_constructor<T>::value
&& ::boost::has_trivial_copy<T>::value
&& ::boost::has_trivial_destructor<T>::value
&& ::boost::is_class<T>::value
&& ::boost::is_empty<T>::value
//////////

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
ue, Aug 4, 2015 at 8:24 AM, Thiago Macieira <span dir=3D"ltr">&lt;<a href=
=3D"mailto:thiago@macieira.org" target=3D"_blank">thiago@macieira.org</a>&g=
t;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0=
 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=3D"">On Tues=
day 04 August 2015 10:13:04 Zach Laine wrote:<br>
&gt; Again, I don&#39;t see the one value you mention.=C2=A0 Please point t=
o the value<br>
&gt; below:<br>
&gt;<br>
&gt; struct foo<br>
&gt; {<br>
&gt; };<br>
&gt;<br>
&gt; Where is it?=C2=A0 Objects of type &quot;foo&quot; have an address, bu=
t no value, right?<br>
&gt; What am I missing?<br>
<br>
</span>It took me some time to understand Matt&#39;s proposition too... the=
re&#39;s a very<br>
subtle difference between types with zero states and types with one state.<=
/blockquote><div><br></div><div>In case there is any confusion, I DO mean s=
truct void {}; I defined in C++ the type in a couple of replies in a hope t=
hat it would eliminate all confusion. If &quot;stateless&quot; is the confu=
sing part, for clarity, I&#39;m referring to the boost definition of statel=
ess -- the docs have always had a standard reference, though it now appears=
 outdated. I didn&#39;t think there would be confusion using this term in t=
his forum. Quoting the docs:</div><div><br></div><div>//////////</div><div>=
<div>A stateless type is a type that has no storage and whose constructors =
and destructors are trivial. That means that is_stateless only inherits fro=
m true_type if the following expression is true:</div><div><br></div><div>:=
:boost::has_trivial_constructor&lt;T&gt;::value</div><div>&amp;&amp; ::boos=
t::has_trivial_copy&lt;T&gt;::value</div><div>&amp;&amp; ::boost::has_trivi=
al_destructor&lt;T&gt;::value</div><div>&amp;&amp; ::boost::is_class&lt;T&g=
t;::value</div><div>&amp;&amp; ::boost::is_empty&lt;T&gt;::value</div></div=
><div>//////////</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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a113cd18c5537e2051c800b9d--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Tue, 04 Aug 2015 11:30:44 -0700
Raw View
On Tuesday 04 August 2015 10:59:14 'Matt Calabrese' via ISO C++ Standard -
Future Proposals wrote:
> In case there is any confusion, I DO mean struct void {}; I defined in C++
> the type in a couple of replies in a hope that it would eliminate all
> confusion

You've failed in eliminating confusion.

Please choose one only:

a) struct void {};
b) zero states

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

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Tue, 04 Aug 2015 11:31:58 -0700
Raw View
On Tuesday 04 August 2015 11:54:32 Zach Laine wrote:
> Stop right there.  You are using the value of the discriminator
> "x.which()", which is an int with a runtime value.  You never used the
> values of empty1() and empty2().

There's no need to, because they can only assume one possible value.

It's like checking whether a value of type std::nullptr_t is null. It is, you
don't have to check.
--
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/.

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Tue, 4 Aug 2015 11:36:03 -0700
Raw View
--001a113cd41a0134d8051c808f29
Content-Type: text/plain; charset=UTF-8

On Tue, Aug 4, 2015 at 8:41 AM, Thiago Macieira <thiago@macieira.org> wrote:

> On Tuesday 04 August 2015 10:36:03 Zach Laine wrote:
> > I'm a bit confused by your response.  IFAICT, Matt is suggesting that
> void
> > behave as if it were defined as struct void{}.  Right?
>
> I thought he was, until the discussion on std::tuple<int, void, int>.
>

What did I say that caused the confusion there? I still mean struct void
{}; (and the Regular overloads). Refer to the definition I gave at the
start of all of this. tuple behavior I described should not go against that
and if I specified otherwise somewhere then I was in error.

To be absolutely clear, std::tuple<int, void, int> is just a tuple with 3
elements: an int, a void, and an int. a make_tuple invocation takes 3
parameters -- an int, a void, and an int (technically references). You
would invoke it, usually in generic code, just as anything else:
make_tuple(int_fun(), void_fun(), int_fun()). I further suggest that we may
want to consider supporting syntactic sugar for constructing void, which
would be a whitespace argument, in an attempt to bridge the gap when people
update functions to now take a single void parameter, though currently do
not (promise's set_value(), for example). In other words, you could
equivalently call make_tuple(int_fun(), , int_fun()). The reason why this
is somewhat compelling is it means that you can allow the nullary and unary
void case to be invoked the same way, and just avoid ambiguities by
preferring the nullary overload as a better match if there are multiple
candidates. This syntactic sugar is at least a little bit risky, because it
has some chance of breaking old code (particularly due to the potential
need for an overload to go through substitution that previously wan't even
considered, and a non-SFINAE failure can occur during that substitution
process, or simply templates may be prematurely instantiated, which can
legitimately alter meaning and behavior of the program).

To explain why this might be something we'd want to at least consider, go
back to std::promise<void>. If we remove the separate specialization and
instead rely on the default definition, set_value() would now have one
version that takes a void&& and one version that takes a const void&.
However, in real-world code today, people who call set_value() of
std::promise<void> do not pass anything other than the promise itself (as
this). This means that if we simply removed the specialization, it would
definitely break code. If we support the notion of "empty argument
potentially means void()", then this wouldn't break. std::promise is one
example here, but real-world generic code also has specializations like
these. If we want to make minimal breakages in code, this might help, but
it is actually a trade-off in potential changes and isn't strictly sound.
The conservative approach would be to just force people to update their
code, since it doesn't muck with overload resolution, but I'm just throwing
the idea out in the open because it's at least somewhat compelling and the
effect in practice is that less user code would need to be updated. If this
is the part that was causing the confusion, then let me know if it's not
more clear.

--

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

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

<div dir=3D"ltr">On Tue, Aug 4, 2015 at 8:41 AM, Thiago Macieira=C2=A0<span=
 dir=3D"ltr">&lt;<a href=3D"mailto:thiago@macieira.org" target=3D"_blank">t=
hiago@macieira.org</a>&gt;</span>=C2=A0wrote:<br><blockquote class=3D"gmail=
_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left=
-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span cla=
ss=3D"">On Tuesday 04 August 2015 10:36:03 Zach Laine wrote:<br>&gt; I&#39;=
m a bit confused by your response.=C2=A0 IFAICT, Matt is suggesting that vo=
id<br>&gt; behave as if it were defined as struct void{}.=C2=A0 Right?<br><=
br></span>I thought he was, until the discussion on std::tuple&lt;int, void=
, int&gt;.<br></blockquote><div><br></div><div>What did I say that caused t=
he confusion there? I still mean struct void {}; (and the Regular overloads=
). Refer to the definition I gave at the start of all of this. tuple behavi=
or I described should not go against that and if I specified otherwise some=
where then I was in error.</div><div><br></div><div>To be absolutely clear,=
 std::tuple&lt;int, void, int&gt; is just a tuple with 3 elements: an int, =
a void, and an int. a make_tuple invocation takes 3 parameters -- an int, a=
 void, and an int (technically references). You would invoke it, usually in=
 generic code, just as anything else: make_tuple(int_fun(), void_fun(), int=
_fun()). I further suggest that we may want to consider supporting syntacti=
c sugar for constructing void, which would be a whitespace argument, in an =
attempt to bridge the gap when people update functions to now take a single=
 void parameter, though currently do not (promise&#39;s set_value(), for ex=
ample). In other words, you could equivalently call make_tuple(int_fun(), ,=
 int_fun()). The reason why this is somewhat compelling is it means that yo=
u can allow the nullary and unary void case to be invoked the same way, and=
 just avoid ambiguities by preferring the nullary overload as a better matc=
h if there are multiple candidates. This syntactic sugar is at least a litt=
le bit risky, because it has some chance of breaking old code (particularly=
 due to the potential need for an overload to go through substitution that =
previously wan&#39;t even considered, and a non-SFINAE failure can occur du=
ring that substitution process, or simply templates may be prematurely inst=
antiated, which can legitimately alter meaning and behavior of the program)=
..</div><div><br></div><div>To explain why this might be something we&#39;d =
want to at least consider, go back to std::promise&lt;void&gt;. If we remov=
e the separate specialization and instead rely on the default definition, s=
et_value() would now have one version that takes a void&amp;&amp; and one v=
ersion that takes a const void&amp;. However, in real-world code today, peo=
ple who call set_value() of std::promise&lt;void&gt; do not pass anything o=
ther than the promise itself (as this). This means that if we simply remove=
d the specialization, it would definitely break code. If we support the not=
ion of &quot;empty argument potentially means void()&quot;, then this would=
n&#39;t break. std::promise is one example here, but real-world generic cod=
e also has specializations like these. If we want to make minimal breakages=
 in code, this might help, but it is actually a trade-off in potential chan=
ges and isn&#39;t strictly sound. The conservative approach would be to jus=
t force people to update their code, since it doesn&#39;t muck with overloa=
d resolution, but I&#39;m just throwing the idea out in the open because it=
&#39;s at least somewhat compelling and the effect in practice is that less=
 user code would need to be updated. If this is the part that was causing t=
he confusion, then let me know if it&#39;s not more clear.</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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a113cd41a0134d8051c808f29--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Tue, 4 Aug 2015 11:47:39 -0700
Raw View
--047d7b33d3c07c67e2051c80b8a1
Content-Type: text/plain; charset=UTF-8

On Tue, Aug 4, 2015 at 11:30 AM, Thiago Macieira <thiago@macieira.org>
wrote:

> On Tuesday 04 August 2015 10:59:14 'Matt Calabrese' via ISO C++ Standard -
> Future Proposals wrote:
> > In case there is any confusion, I DO mean struct void {}; I defined in
> C++
> > the type in a couple of replies in a hope that it would eliminate all
> > confusion
>
> You've failed in eliminating confusion.


> Please choose one only:
>
> a) struct void {};
> b) zero states


I think that did clarify, but to be very clear, it's more akin to (a)
without actually being a user-defined type. I'm using actual type
definitions and standard terms in replies so that we don't have to go into
the semantics of this stuff. If there is some ambiguity in terms, prefer
the c++ standard meaning.

So, restated, I absolutely do not mean that void should be something less
than or different from a complete type in C++. It should just be equivalent
to a type with no members that is Regular. This should not be a new kind of
entity for the language with its own semantics, as that would not aid in
writing generic code. It would mean more special casing. All that we need
for void is for it to be a regular type.

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
ue, Aug 4, 2015 at 11:30 AM, Thiago Macieira <span dir=3D"ltr">&lt;<a href=
=3D"mailto:thiago@macieira.org" target=3D"_blank">thiago@macieira.org</a>&g=
t;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0=
 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Tuesday 04 August 201=
5 10:59:14 &#39;Matt Calabrese&#39; via ISO C++ Standard -<br>
<span class=3D"">Future Proposals wrote:<br>
&gt; In case there is any confusion, I DO mean struct void {}; I defined in=
 C++<br>
&gt; the type in a couple of replies in a hope that it would eliminate all<=
br>
&gt; confusion<br>
<br>
</span>You&#39;ve failed in eliminating confusion.=C2=A0</blockquote><block=
quote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc=
 solid;padding-left:1ex">
<br>
Please choose one only:<br>
<br>
a) struct void {};<br>
b) zero states</blockquote><div><br></div><div>I think that did clarify, bu=
t to be very clear, it&#39;s more akin to (a) without actually being a user=
-defined type. I&#39;m using actual type definitions and standard terms in =
replies so that we don&#39;t have to go into the semantics of this stuff. I=
f there is some ambiguity in terms, prefer the c++ standard meaning.</div><=
div><br></div><div>So, restated, I absolutely do not mean that void should =
be something less than or different from a complete type in C++. It should =
just be equivalent to a type with no members that is Regular. This should n=
ot be a new kind of entity for the language with its own semantics, as that=
 would not aid in writing generic code. It would mean more special casing. =
All that we need for void is for it to be a regular type.</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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--047d7b33d3c07c67e2051c80b8a1--

.


Author: Patrice Roy <patricer@gmail.com>
Date: Tue, 4 Aug 2015 15:38:16 -0400
Raw View
--001a11c34b6c761294051c816d10
Content-Type: text/plain; charset=UTF-8

I think it's reasonable to claim that since we can do such things as

bool is_empty1(empty1) { return true; }
bool is_empty1(...) { return false; }

auto x = empty1{};
if (is_empty1(x))
{
   // ...
}

we can hold that a monostate type such as empty1 has a value.

I'm not sure where to go to with changes to the semantics of void, as it
has far-ranging implications, but monostates and values seem reasonable to
me.

2015-08-04 11:41 GMT-04:00 Zach Laine <whatwasthataddress@gmail.com>:

> On Tue, Aug 4, 2015 at 10:32 AM, Paul Fultz II <pfultz28@gmail.com> wrote:
>
>>
>>
>> On Tuesday, August 4, 2015 at 10:13:07 AM UTC-5, Zach Laine wrote:
>>>
>>> On Tue, Aug 4, 2015 at 9:57 AM, Paul Fultz II <pful...@gmail.com> wrote:
>>>
>>>>
>>>> On Tuesday, August 4, 2015 at 4:00:41 AM UTC-5, Bengt Gustafsson wrote:
>>>>>
>>>>> How about just defining that void behaves like an empty struct? This
>>>>> avoids us having to discuss every particular case. There are still the
>>>>> potentials for code breakage with tricky SFINAE but I don't see how that
>>>>> can ever be avoided if we change the behaviour of void at all. Note: I
>>>>> don't mean that void should BE an empty struct in that you can inherit from
>>>>> it, but that it acts like one when used in code.
>>>>>
>>>>
>>>> But having void act like an empty struct, then it becomes a type with
>>>> one value. However, `void` should mean a type with zero values(like a
>>>> function that doesn't return anything). Of course, changing `void` from
>>>> having zero values to one value could break a lot of assumptions made about
>>>> code. I think its a bad idea. For some generic code, it may be safe to
>>>> assume void as having one value instead of zero, but it would be better to
>>>> use a library solution for this instead of baking in potential unsafe type
>>>> assumptions into the language.
>>>>
>>>
>>> Again, I don't see the one value you mention.  Please point to the value
>>> below:
>>>
>>> struct foo
>>> {
>>> };
>>>
>>> Where is it?  Objects of type "foo" have an address, but no value,
>>> right?  What am I missing?
>>>
>>
>>
>> Its `foo()`. Thats the one value. You can assign it to a variable:
>>
>> auto x = foo();
>>
>> So what value does `x` have? It has to have a value, and it is `foo()`.
>> Futhermore, you can return its value from a function:
>>
>> foo f()
>> { return foo(); }
>>
>> If `foo` didn't have a value, then we wouldn't be able to return it from
>> a function. Also, you can observe that the values start to add up when we
>> start to sum them using a variant. How many values does `foo` have now?
>>
>> struct empty1 {};
>> struct empty2 {};
>>
>> typedef variant<empty1, empty2> foo;
>>
>> It has two: `empty1()` and `empty2()`.
>>
>
> Please write an if statement predicated on the values of empty1() and
> empty2() that takes different paths depending on runtime state, without
> relying on UB.
>
> My point is that there is no non-UB-invoking observable runtime state for
> these objects.  They have no values that are meaningful to my program's
> state.  They are meaningful at compile time only.
>
> Zach
>
> --
>
> ---
> 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/.

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

<div dir=3D"ltr"><div><div><div><div><div>I think it&#39;s reasonable to cl=
aim that since we can do such things as<br><br></div>bool is_empty1(empty1)=
 { return true; }<br>bool is_empty1(...) { return false; }<br><br></div>aut=
o x =3D empty1{};<br></div>if (is_empty1(x))<br>{<br>=C2=A0=C2=A0 // ...<br=
>}<br><br></div>we can hold that a monostate type such as empty1 has a valu=
e.<br><br></div>I&#39;m not sure where to go to with changes to the semanti=
cs of void, as it has far-ranging implications, but monostates and values s=
eem reasonable to me.<br></div><div class=3D"gmail_extra"><br><div class=3D=
"gmail_quote">2015-08-04 11:41 GMT-04:00 Zach Laine <span dir=3D"ltr">&lt;<=
a href=3D"mailto:whatwasthataddress@gmail.com" target=3D"_blank">whatwastha=
taddress@gmail.com</a>&gt;</span>:<br><blockquote class=3D"gmail_quote" sty=
le=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div d=
ir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><span clas=
s=3D"">On Tue, Aug 4, 2015 at 10:32 AM, Paul Fultz II <span dir=3D"ltr">&lt=
;<a href=3D"mailto:pfultz28@gmail.com" target=3D"_blank">pfultz28@gmail.com=
</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin=
:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br><br>On Tuesday=
, August 4, 2015 at 10:13:07 AM UTC-5, Zach Laine wrote:<span><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #c=
cc solid;padding-left:1ex"><div dir=3D"ltr"><div><div class=3D"gmail_quote"=
>On Tue, Aug 4, 2015 at 9:57 AM, Paul Fultz II <span dir=3D"ltr">&lt;<a rel=
=3D"nofollow">pful...@gmail.com</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"><div dir=3D"ltr"><br>On Tuesday, August 4, 2015 at 4:00:41 AM=
 UTC-5, Bengt Gustafsson wrote:<blockquote class=3D"gmail_quote" style=3D"m=
argin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div=
 dir=3D"ltr">How about just defining that void behaves like an empty struct=
? This avoids us having to discuss every particular case. There are still t=
he potentials for code breakage with tricky SFINAE but I don&#39;t see how =
that can ever be avoided if we change the behaviour of void at all. Note: I=
 don&#39;t mean that void should BE an empty struct in that you can inherit=
 from it, but that it acts like one when used in code.<br></div></blockquot=
e><div>=C2=A0<br>But having void act like an empty struct, then it becomes =
a type with one value. However, `void` should mean a type with zero values(=
like a function that doesn&#39;t return anything). Of course, changing `voi=
d` from having zero values to one value could break a lot of assumptions ma=
de about code. I think its a bad idea. For some generic code, it may be saf=
e to assume void as having one value instead of zero, but it would be bette=
r to use a library solution for this instead of baking in potential unsafe =
type assumptions into the language.</div></div></blockquote><div><br></div>=
<div>Again, I don&#39;t see the one value you mention.=C2=A0 Please point t=
o the value below:</div><div><br></div><div>struct foo</div><div>{</div><di=
v>};</div><div><br></div><div>Where is it?=C2=A0 Objects of type &quot;foo&=
quot; have an address, but no value, right?=C2=A0 What am I missing?=C2=A0<=
/div></div></div></div></blockquote></span><div><br><br>Its `foo()`. Thats =
the one value. You can assign it to a variable:<br><br>auto x =3D foo();<br=
><br>So what value does `x` have? It has to have a value, and it is `foo()`=
.. Futhermore, you can return its value from a function:<br><br>foo f()<br>{=
 return foo(); }<br><br>If `foo` didn&#39;t have a value, then we wouldn&#3=
9;t be able to return it from a function. Also, you can observe that the va=
lues start to add up when we start to sum them using a variant. How many va=
lues does `foo` have now?<br><br>struct empty1 {};<br>struct empty2 {};<br>=
<br>typedef variant&lt;empty1, empty2&gt; foo;<br><br>It has two: `empty1()=
` and `empty2()`. <br></div></blockquote><div><br></div></span><div>Please =
write an if statement predicated on the values of empty1() and empty2() tha=
t takes different paths depending on runtime state, without relying on UB.<=
/div><div><br></div><div>My point is that there is no non-UB-invoking obser=
vable runtime state for these objects.=C2=A0 They have no values that are m=
eaningful to my program&#39;s state.=C2=A0 They are meaningful at compile t=
ime only.</div><span class=3D"HOEnZb"><font color=3D"#888888"><div><br></di=
v><div>Zach</div></font></span></div></div></div><div class=3D"HOEnZb"><div=
 class=3D"h5">

<p></p>

-- <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+unsubscribe@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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a11c34b6c761294051c816d10--

.


Author: Zach Laine <whatwasthataddress@gmail.com>
Date: Tue, 4 Aug 2015 15:58:34 -0500
Raw View
--f46d04430440a96496051c828cef
Content-Type: text/plain; charset=UTF-8

On Tue, Aug 4, 2015 at 1:31 PM, Thiago Macieira <thiago@macieira.org> wrote:

> On Tuesday 04 August 2015 11:54:32 Zach Laine wrote:
> > Stop right there.  You are using the value of the discriminator
> > "x.which()", which is an int with a runtime value.  You never used the
> > values of empty1() and empty2().
>
> There's no need to, because they can only assume one possible value.
>
> It's like checking whether a value of type std::nullptr_t is null. It is,
> you
> don't have to check.
>

That is precisely my point.  This discussion started with Paul's statement
that use of the "struct void{}:" definition injects extra state into your
program that was not there before.  I haven't yet seen it.

Zach

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
ue, Aug 4, 2015 at 1:31 PM, Thiago Macieira <span dir=3D"ltr">&lt;<a href=
=3D"mailto:thiago@macieira.org" target=3D"_blank">thiago@macieira.org</a>&g=
t;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0=
 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=3D"">On Tues=
day 04 August 2015 11:54:32 Zach Laine wrote:<br>
&gt; Stop right there.=C2=A0 You are using the value of the discriminator<b=
r>
&gt; &quot;x.which()&quot;, which is an int with a runtime value.=C2=A0 You=
 never used the<br>
&gt; values of empty1() and empty2().<br>
<br>
</span>There&#39;s no need to, because they can only assume one possible va=
lue.<br>
<br>
It&#39;s like checking whether a value of type std::nullptr_t is null. It i=
s, you<br>
don&#39;t have to check.<br></blockquote><div><br></div><div>That is precis=
ely my point.=C2=A0 This discussion started with Paul&#39;s statement that =
use of the &quot;struct void{}:&quot; definition injects extra state into y=
our program that was not there before.=C2=A0 I haven&#39;t yet seen it.</di=
v><div><br></div><div>Zach=C2=A0</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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--f46d04430440a96496051c828cef--

.


Author: Magnus Fromreide <magfr@lysator.liu.se>
Date: Tue, 4 Aug 2015 23:05:19 +0200
Raw View
On Tue, Aug 04, 2015 at 10:50:24AM +0100, 'Edward Catmur' via ISO C++ Standard - Future Proposals wrote:
> Yes! Also, deprecate (void) meaning () outside extern "C" - there's no need
> for it, as C++ doesn't have unspecified parameter lists (even in C they're
> obsolescent: 6.11.6 "Future language directions - Function declarators").

I would expect this to needlessly introduce compilation erros in quite a few
code bases and are strongly opposed to it in any near time, but for the
presumed C++4x it might be a reasonable idea...

/MF

> On Tue, Aug 4, 2015 at 10:46 AM, 'Johannes Schaub' via ISO C++ Standard -
> Future Proposals <std-proposals@isocpp.org> wrote:
>
> > Altermatively just give the void parameter a name. A named parameter
> > shouldn't catch the special case of meaning an empty parameter list.
> >
> > Am 04.08.2015 11:40 schrieb "Johannes Schaub" <
> > schaub.johannes@googlemail.com>:
> > >
> > > If we are already in oddballs mode, why not express the nondependent
> > case by dependent types
> > >
> > > template<typename T = void>
> > > void f(typename void_t<T>::type);
> > >
> > > Am 04.08.2015 10:02 schrieb "'Matt Calabrese' via ISO C++ Standard -
> > Future Proposals" <std-proposals@isocpp.org>:
> > > >
> > > > On Tue, Aug 4, 2015 at 12:32 AM, Roland Bock <rbock@eudoxos.de> wrote:
> > > >>
> > > >>
> > > >> How about binary functions?
> > > >>
> > > >> void foo0();              // zero parameters
> > > >> void foo1(void);          // still zero parameters (you say)
> > > >> void foo2(void, void);    // ???
> > > >>
> > > >> and how about
> > > >>
> > > >> void foo2(int, void);     // ???
> > > >> void foo2(void, int);     // ???
> > > >>
> > > >> I would prefer all of them to be different, foo0 having zero
> > parameters, foo1 having one parameters, foo2 having two parameters.
> > > >
> > > >
> > > > Yes!!! They are all logically different, we realistically just can't
> > use the syntax for foo1.
> > > >
> > > >> We could however introduce a new thing, e.g. std::none, that could be
> > designed from afresh and have all the nice features we would like to see in
> > void
> > > >
> > > >
> > > > Unfortunately that wouldn't help generic code unless everyone just
> > updated all of their code over night and nobody instantiated templates with
> > void, which realistically wouldn't happen. void is going to stay so ideally
> > we actually fix it in some way. IMO, we're really close to getting there.
> > The only thing we don't have IMHO is a good syntax for representing a unary
> > void function when void is not dependent. It's fine if there is an odd-ball
> > syntax for it because the dependent case is the one that comes up in
> > generic code. You wouldn't need to use the weird syntax there.
> > > >
> > > > One possible solution -- we could have unary void functions declared
> > as:
> > > >
> > > > /////
> > > > void foo(explicit void) {}
> > > > /////
> > > >
> > > > This is syntax that was illegal before, introduces no new keywords or
> > types, and doesn't look too obscure. There are probably many alternatives
> > and I'm not saying this is what it should be, we'd just need to pick one
> > that makes the most sense.
> > > >
> >
> > --
> >
> > ---
> > You received this message because you are subscribed to a topic in the
> > Google Groups "ISO C++ Standard - Future Proposals" group.
> > To unsubscribe from this topic, visit
> > https://groups.google.com/a/isocpp.org/d/topic/std-proposals/05prNzycvYU/unsubscribe
> > .
> > To unsubscribe from this group and all its topics, 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: "'Edward Catmur' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Tue, 4 Aug 2015 23:30:46 +0100
Raw View
--047d7b6222e462bb29051c83d676
Content-Type: text/plain; charset=UTF-8

Previously a variant<bool, void> could have two values: true or false. Now
it can have three values: true, false or void{}. There's your extra state.
On 4 Aug 2015 22:06, "Zach Laine" <whatwasthataddress@gmail.com> wrote:

> On Tue, Aug 4, 2015 at 1:31 PM, Thiago Macieira <thiago@macieira.org>
> wrote:
>
>> On Tuesday 04 August 2015 11:54:32 Zach Laine wrote:
>> > Stop right there.  You are using the value of the discriminator
>> > "x.which()", which is an int with a runtime value.  You never used the
>> > values of empty1() and empty2().
>>
>> There's no need to, because they can only assume one possible value.
>>
>> It's like checking whether a value of type std::nullptr_t is null. It is,
>> you
>> don't have to check.
>>
>
> That is precisely my point.  This discussion started with Paul's statement
> that use of the "struct void{}:" definition injects extra state into your
> program that was not there before.  I haven't yet seen it.
>
> Zach
>
> --
>
> ---
> You received this message because you are subscribed to a topic in the
> Google Groups "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/a/isocpp.org/d/topic/std-proposals/05prNzycvYU/unsubscribe
> .
> To unsubscribe from this group and all its topics, 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/.

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

<p dir=3D"ltr">Previously a variant&lt;bool, void&gt; could have two values=
: true or false. Now it can have three values: true, false or void{}. There=
&#39;s your extra state. </p>
<div class=3D"gmail_quote">On 4 Aug 2015 22:06, &quot;Zach Laine&quot; &lt;=
<a href=3D"mailto:whatwasthataddress@gmail.com">whatwasthataddress@gmail.co=
m</a>&gt; wrote:<br type=3D"attribution"><blockquote class=3D"gmail_quote" =
style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><di=
v dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On Tue,=
 Aug 4, 2015 at 1:31 PM, Thiago Macieira <span dir=3D"ltr">&lt;<a href=3D"m=
ailto:thiago@macieira.org" target=3D"_blank">thiago@macieira.org</a>&gt;</s=
pan> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex=
;border-left:1px #ccc solid;padding-left:1ex"><span>On Tuesday 04 August 20=
15 11:54:32 Zach Laine wrote:<br>
&gt; Stop right there.=C2=A0 You are using the value of the discriminator<b=
r>
&gt; &quot;x.which()&quot;, which is an int with a runtime value.=C2=A0 You=
 never used the<br>
&gt; values of empty1() and empty2().<br>
<br>
</span>There&#39;s no need to, because they can only assume one possible va=
lue.<br>
<br>
It&#39;s like checking whether a value of type std::nullptr_t is null. It i=
s, you<br>
don&#39;t have to check.<br></blockquote><div><br></div><div>That is precis=
ely my point.=C2=A0 This discussion started with Paul&#39;s statement that =
use of the &quot;struct void{}:&quot; definition injects extra state into y=
our program that was not there before.=C2=A0 I haven&#39;t yet seen it.</di=
v><div><br></div><div>Zach=C2=A0</div></div></div></div>

<p></p>

-- <br>
<br>
--- <br>
You received this message because you are subscribed to a topic in the Goog=
le Groups &quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this topic, visit <a href=3D"https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/05prNzycvYU/unsubscribe" target=3D"_blan=
k">https://groups.google.com/a/isocpp.org/d/topic/std-proposals/05prNzycvYU=
/unsubscribe</a>.<br>
To unsubscribe from this group and all its topics, send an email to <a href=
=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_blank">std-prop=
osals+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>
</blockquote></div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--047d7b6222e462bb29051c83d676--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Tue, 04 Aug 2015 15:35:59 -0700
Raw View
On Tuesday 04 August 2015 23:30:46 'Edward Catmur' via ISO C++ Standard -
Future Proposals wrote:
> Previously a variant<bool, void> could have two values: true or false. Now
> it can have three values: true, false or void{}. There's your extra state.

If the variant could never have assumed the void type as its state, then why
was void even allowed in the template parameter list in the first place?

Sounds like a design defect to me.
--
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/.

.


Author: Paul Fultz II <pfultz28@gmail.com>
Date: Tue, 4 Aug 2015 15:45:18 -0700 (PDT)
Raw View
------=_Part_1729_1442882916.1438728318909
Content-Type: multipart/alternative;
 boundary="----=_Part_1730_1871521700.1438728318917"

------=_Part_1730_1871521700.1438728318917
Content-Type: text/plain; charset=UTF-8



On Tuesday, August 4, 2015 at 3:58:36 PM UTC-5, Zach Laine wrote:
>
> On Tue, Aug 4, 2015 at 1:31 PM, Thiago Macieira <thi...@macieira.org
> <javascript:>> wrote:
>
>> On Tuesday 04 August 2015 11:54:32 Zach Laine wrote:
>> > Stop right there.  You are using the value of the discriminator
>> > "x.which()", which is an int with a runtime value.  You never used the
>> > values of empty1() and empty2().
>>
>> There's no need to, because they can only assume one possible value.
>>
>> It's like checking whether a value of type std::nullptr_t is null. It is,
>> you
>> don't have to check.
>>
>
> That is precisely my point.  This discussion started with Paul's statement
> that use of the "struct void{}:" definition injects extra state into your
> program that was not there before.  I haven't yet seen it.
>

If `void` has zero values then `bool`, `variant<empty1, empty2>`,
`variant<empty1, empty2, void>` all have same number of values. However, if
we define `void` as `struct void {};` then `variant<empty1, empty2, void>`
has the same number of values as tribool. Essentially, adding an extra
state to the types. This is example is trivial and obvious, however, since
the assumptions of `void` is that it has no values, it could subtly easily
break other assumptions in the program.

Also, having a type represent zero values is really necessary for
completeness, especially if we add variant to the language since `void` is
the identity element for variant. Plus, the identity element would allow
monadic computations over variant types, which could help with defining
DSLs.


>
> Zach
>

--

---
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_1730_1871521700.1438728318917
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<br><br>On Tuesday, August 4, 2015 at 3:58:36 PM UTC-5, Zach Laine wrote:<b=
lockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;borde=
r-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=
=3D"gmail_quote">On Tue, Aug 4, 2015 at 1:31 PM, Thiago Macieira <span dir=
=3D"ltr">&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailt=
o=3D"AbCFtXj7DwAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascr=
ipt:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return=
 true;">thi...@macieira.org</a>&gt;</span> wrote:<br><blockquote class=3D"g=
mail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-l=
eft:1ex"><span>On Tuesday 04 August 2015 11:54:32 Zach Laine wrote:<br>
&gt; Stop right there.=C2=A0 You are using the value of the discriminator<b=
r>
&gt; &quot;x.which()&quot;, which is an int with a runtime value.=C2=A0 You=
 never used the<br>
&gt; values of empty1() and empty2().<br>
<br>
</span>There&#39;s no need to, because they can only assume one possible va=
lue.<br>
<br>
It&#39;s like checking whether a value of type std::nullptr_t is null. It i=
s, you<br>
don&#39;t have to check.<br></blockquote><div><br></div><div>That is precis=
ely my point.=C2=A0 This discussion started with Paul&#39;s statement that =
use of the &quot;struct void{}:&quot; definition injects extra state into y=
our program that was not there before.=C2=A0 I haven&#39;t yet seen it.</di=
v></div></div></div></blockquote><div><br>If `void` has zero values then `b=
ool`, `variant&lt;empty1, empty2&gt;`, `variant&lt;empty1, empty2, void&gt;=
` all have same number of values. However, if we define `void` as `struct v=
oid {};` then `variant&lt;empty1, empty2, void&gt;` has the same number of =
values as tribool. Essentially, adding an extra state to the types. This is=
 example is trivial and obvious, however, since the assumptions of `void` i=
s that it has no values, it could subtly easily break other assumptions in =
the program.<br><br>Also, having a type represent zero values is really nec=
essary for completeness, especially if we add variant to the language since=
 `void` is the identity element for variant. Plus, the identity element wou=
ld allow monadic computations over variant types, which could help with def=
ining DSLs.<br>=C2=A0</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><br></div><div>Zach=C2=
=A0</div></div></div></div>
</blockquote>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_1730_1871521700.1438728318917--
------=_Part_1729_1442882916.1438728318909--

.


Author: "'Edward Catmur' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Tue, 4 Aug 2015 23:46:39 +0100
Raw View
--047d7b6222e437f812051c840f8f
Content-Type: text/plain; charset=UTF-8

I'm not so sure - last I looked you could form tuple<int, void> despite the
resulting type being non-instantiable i.e. nullary. Such things have their
uses.
On 4 Aug 2015 23:36, "Thiago Macieira" <thiago@macieira.org> wrote:

> On Tuesday 04 August 2015 23:30:46 'Edward Catmur' via ISO C++ Standard -
> Future Proposals wrote:
> > Previously a variant<bool, void> could have two values: true or false.
> Now
> > it can have three values: true, false or void{}. There's your extra
> state.
>
> If the variant could never have assumed the void type as its state, then
> why
> was void even allowed in the template parameter list in the first place?
>
> Sounds like a design defect to me.
> --
> 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 a topic in the
> Google Groups "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/a/isocpp.org/d/topic/std-proposals/05prNzycvYU/unsubscribe
> .
> To unsubscribe from this group and all its topics, 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/.

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

<p dir=3D"ltr">I&#39;m not so sure - last I looked you could form tuple&lt;=
int, void&gt; despite the resulting type being non-instantiable i.e. nullar=
y. Such things have their uses. </p>
<div class=3D"gmail_quote">On 4 Aug 2015 23:36, &quot;Thiago Macieira&quot;=
 &lt;<a href=3D"mailto:thiago@macieira.org">thiago@macieira.org</a>&gt; wro=
te:<br type=3D"attribution"><blockquote class=3D"gmail_quote" style=3D"marg=
in:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Tuesday 04 Au=
gust 2015 23:30:46 &#39;Edward Catmur&#39; via ISO C++ Standard -<br>
Future Proposals wrote:<br>
&gt; Previously a variant&lt;bool, void&gt; could have two values: true or =
false. Now<br>
&gt; it can have three values: true, false or void{}. There&#39;s your extr=
a state.<br>
<br>
If the variant could never have assumed the void type as its state, then wh=
y<br>
was void even allowed in the template parameter list in the first place?<br=
>
<br>
Sounds like a design defect to me.<br>
--<br>
Thiago Macieira - thiago (AT) <a href=3D"http://macieira.info" rel=3D"noref=
errer" target=3D"_blank">macieira.info</a> - thiago (AT) <a href=3D"http://=
kde.org" rel=3D"noreferrer" 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=A0 966C 33F5 F005 6EF4 535=
8<br>
<br>
--<br>
<br>
---<br>
You received this message because you are subscribed to a topic in the Goog=
le Groups &quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this topic, visit <a href=3D"https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/05prNzycvYU/unsubscribe" rel=3D"noreferr=
er" target=3D"_blank">https://groups.google.com/a/isocpp.org/d/topic/std-pr=
oposals/05prNzycvYU/unsubscribe</a>.<br>
To unsubscribe from this group and all its topics, send an email to <a href=
=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org">std-proposals+unsubscrib=
e@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/" rel=3D"noreferrer" target=3D"_blank">http://groups.google.c=
om/a/isocpp.org/group/std-proposals/</a>.<br>
</blockquote></div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--047d7b6222e437f812051c840f8f--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Tue, 4 Aug 2015 15:53:57 -0700
Raw View
--001a113cd41a4c8314051c84293d
Content-Type: text/plain; charset=UTF-8

On Tue, Aug 4, 2015 at 3:35 PM, Thiago Macieira <thiago@macieira.org> wrote:

> On Tuesday 04 August 2015 23:30:46 'Edward Catmur' via ISO C++ Standard -
> Future Proposals wrote:
> > Previously a variant<bool, void> could have two values: true or false.
> Now
> > it can have three values: true, false or void{}. There's your extra
> state.
>
> If the variant could never have assumed the void type as its state, then
> why
> was void even allowed in the template parameter list in the first place?
>
> Sounds like a design defect to me.


+1 Unless there is some generic case that people have in mind and haven't
actually expressed, there is no explanation for why anyone would want this
special behavior for void.

Unless people have a clear, practical rationale for this other kind of
entity, I don't understand why it's even being discussed. What value would
it supposedly provide? All I see is more special casing, no aid in generic
programming, and no example of why you would want this in practice. If it's
just because people are clinging to a preconceived notion of "true"
emptiness, then I think we need to just accept that thinking of the void
data type in such a manner simply is not what would solve any of the
problems that we set out to solve. I'm not refuting that such a notion is
valid, only that there is no reason for us to have void model this
particular concept. Unless there is a practical example for *why* one would
want that particular representation of void, it's silly to even continue
down this path. In what cases would such a representation benefit our code?
It certainly doesn't simplify generic code in any way that the struct void
{}; does.

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
ue, Aug 4, 2015 at 3:35 PM, Thiago Macieira <span dir=3D"ltr">&lt;<a href=
=3D"mailto:thiago@macieira.org" target=3D"_blank">thiago@macieira.org</a>&g=
t;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0=
 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Tuesday 04 August 201=
5 23:30:46 &#39;Edward Catmur&#39; via ISO C++ Standard -<br>
<span class=3D"">Future Proposals wrote:<br>
&gt; Previously a variant&lt;bool, void&gt; could have two values: true or =
false. Now<br>
&gt; it can have three values: true, false or void{}. There&#39;s your extr=
a state.<br>
<br>
</span>If the variant could never have assumed the void type as its state, =
then why<br>
was void even allowed in the template parameter list in the first place?<br=
>
<br>
Sounds like a design defect to me.</blockquote><div><br></div><div>+1 Unles=
s there is some generic case that people have in mind and haven&#39;t actua=
lly expressed, there is no explanation for why anyone would want this speci=
al behavior for void.</div><div><br></div><div>Unless people have a clear, =
practical rationale for this other kind of entity, I don&#39;t understand w=
hy it&#39;s even being discussed. What value would it supposedly provide? A=
ll I see is more special casing, no aid in generic programming, and no exam=
ple of why you would want this in practice. If it&#39;s just because people=
 are clinging to a preconceived notion of &quot;true&quot; emptiness, then =
I think we need to just accept that thinking of the void data type in such =
a manner simply is not what would solve any of the problems that we set out=
 to solve. I&#39;m not refuting that such a notion is valid, only that ther=
e is no reason for us to have void model this particular concept. Unless th=
ere is a practical example for <i>why</i>=C2=A0one would want that particul=
ar representation of void, it&#39;s silly to even continue down this path. =
In what cases would such a representation benefit our code? It certainly do=
esn&#39;t simplify generic code in any way that the struct void {}; does.</=
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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a113cd41a4c8314051c84293d--

.


Author: Zach Laine <whatwasthataddress@gmail.com>
Date: Tue, 4 Aug 2015 17:58:38 -0500
Raw View
--047d7bae48f412cce1051c843a44
Content-Type: text/plain; charset=UTF-8

On Tue, Aug 4, 2015 at 5:30 PM, 'Edward Catmur' via ISO C++ Standard -
Future Proposals <std-proposals@isocpp.org> wrote:

> Previously a variant<bool, void> could have two values: true or false. Now
> it can have three values: true, false or void{}. There's your extra state.
>
I think previously a variant<bool, void> had 3 states: bool-true,
bool-false, and void.  In other words, the discriminator could have been 0,
indicating that the bool type was active, or 1, indicating that the void
type was active.  There were two states (true and false) within the
discriminator==0 case, and only one within the discriminator==1 case.
Right?

Zach

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
ue, Aug 4, 2015 at 5:30 PM, &#39;Edward Catmur&#39; via ISO C++ Standard - =
Future Proposals <span dir=3D"ltr">&lt;<a href=3D"mailto:std-proposals@isoc=
pp.org" target=3D"_blank">std-proposals@isocpp.org</a>&gt;</span> wrote:<br=
><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1=
px #ccc solid;padding-left:1ex"><p dir=3D"ltr">Previously a variant&lt;bool=
, void&gt; could have two values: true or false. Now it can have three valu=
es: true, false or void{}. There&#39;s your extra state.</p></blockquote><d=
iv>I think previously a variant&lt;bool, void&gt; had 3 states: bool-true, =
bool-false, and void.=C2=A0 In other words, the discriminator could have be=
en 0, indicating that the bool type was active, or 1, indicating that the v=
oid type was active.=C2=A0 There were two states (true and false) within th=
e discriminator=3D=3D0 case, and only one within the discriminator=3D=3D1 c=
ase.=C2=A0 Right?</div><div><br></div><div>Zach</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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--047d7bae48f412cce1051c843a44--

.


Author: "'Edward Catmur' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Wed, 5 Aug 2015 00:08:13 +0100
Raw View
--001a11c33bb052c8c2051c845ca8
Content-Type: text/plain; charset=UTF-8

If void is nullary (which it is at present, pretty much) then variant<bool,
void> could only have a discriminant of 0; the void type could not be
active because it is not possible to have a value of type void. Only if
void values are allowed does it become possible for the discriminant to
take a value of 1.
On 4 Aug 2015 23:58, "Zach Laine" <whatwasthataddress@gmail.com> wrote:

> On Tue, Aug 4, 2015 at 5:30 PM, 'Edward Catmur' via ISO C++ Standard -
> Future Proposals <std-proposals@isocpp.org> wrote:
>
>> Previously a variant<bool, void> could have two values: true or false.
>> Now it can have three values: true, false or void{}. There's your extra
>> state.
>>
> I think previously a variant<bool, void> had 3 states: bool-true,
> bool-false, and void.  In other words, the discriminator could have been 0,
> indicating that the bool type was active, or 1, indicating that the void
> type was active.  There were two states (true and false) within the
> discriminator==0 case, and only one within the discriminator==1 case.
> Right?
>
> Zach
>
> --
>
> ---
> You received this message because you are subscribed to a topic in the
> Google Groups "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/a/isocpp.org/d/topic/std-proposals/05prNzycvYU/unsubscribe
> .
> To unsubscribe from this group and all its topics, 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/.

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

<p dir=3D"ltr">If void is nullary (which it is at present, pretty much) the=
n variant&lt;bool, void&gt; could only have a discriminant of 0; the void t=
ype could not be active because it is not possible to have a value of type =
void. Only if void values are allowed does it become possible for the discr=
iminant to take a value of 1.</p>
<div class=3D"gmail_quote">On 4 Aug 2015 23:58, &quot;Zach Laine&quot; &lt;=
<a href=3D"mailto:whatwasthataddress@gmail.com">whatwasthataddress@gmail.co=
m</a>&gt; wrote:<br type=3D"attribution"><blockquote class=3D"gmail_quote" =
style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><di=
v dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On Tue,=
 Aug 4, 2015 at 5:30 PM, &#39;Edward Catmur&#39; via ISO C++ Standard - Fut=
ure Proposals <span dir=3D"ltr">&lt;<a href=3D"mailto:std-proposals@isocpp.=
org" target=3D"_blank">std-proposals@isocpp.org</a>&gt;</span> wrote:<br><b=
lockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px =
#ccc solid;padding-left:1ex"><p dir=3D"ltr">Previously a variant&lt;bool, v=
oid&gt; could have two values: true or false. Now it can have three values:=
 true, false or void{}. There&#39;s your extra state.</p></blockquote><div>=
I think previously a variant&lt;bool, void&gt; had 3 states: bool-true, boo=
l-false, and void.=C2=A0 In other words, the discriminator could have been =
0, indicating that the bool type was active, or 1, indicating that the void=
 type was active.=C2=A0 There were two states (true and false) within the d=
iscriminator=3D=3D0 case, and only one within the discriminator=3D=3D1 case=
..=C2=A0 Right?</div><div><br></div><div>Zach</div></div></div></div>

<p></p>

-- <br>
<br>
--- <br>
You received this message because you are subscribed to a topic in the Goog=
le Groups &quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this topic, visit <a href=3D"https://groups.google.com/=
a/isocpp.org/d/topic/std-proposals/05prNzycvYU/unsubscribe" target=3D"_blan=
k">https://groups.google.com/a/isocpp.org/d/topic/std-proposals/05prNzycvYU=
/unsubscribe</a>.<br>
To unsubscribe from this group and all its topics, send an email to <a href=
=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_blank">std-prop=
osals+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>
</blockquote></div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a11c33bb052c8c2051c845ca8--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Tue, 4 Aug 2015 16:15:05 -0700
Raw View
--001a113ccf4ae9d920051c84742b
Content-Type: text/plain; charset=UTF-8

On Tue, Aug 4, 2015 at 3:45 PM, Paul Fultz II <pfultz28@gmail.com> wrote:
>
> Also, having a type represent zero values is really necessary for
> completeness, especially if we add variant to the language since `void` is
> the identity element for variant. Plus, the identity element would allow
> monadic computations over variant types, which could help with defining
> DSLs.
>

I have no doubt that you are trying to make a legitimate point here, but
please ground this with an example, and explain precisely why you feel it
makes sense to reuse "void" as such a type. Again, I don't refute that such
a type is a valid notion, only that it makes no sense for void to be that
type as making void such a type does not solve the actual problems we are
facing. The struct void {}; definition of void makes sensible generic code
work perfectly fine without special-casing void, and I have yet to see even
one practical example from you regarding how this definition of void would
provide any tangible benefit. Write a simple code example showing the
benefit and explains why "void" must be this type.

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
ue, Aug 4, 2015 at 3:45 PM, Paul Fultz II <span dir=3D"ltr">&lt;<a href=3D"=
mailto:pfultz28@gmail.com" target=3D"_blank">pfultz28@gmail.com</a>&gt;</sp=
an> wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bord=
er-left:1px #ccc solid;padding-left:1ex">Also, having a type represent zero=
 values is really necessary for completeness, especially if we add variant =
to the language since `void` is the identity element for variant. Plus, the=
 identity element would allow monadic computations over variant types, whic=
h could help with defining DSLs.<br></blockquote><div><br></div><div>I have=
 no doubt that you are trying to make a legitimate point here, but please g=
round this with an example, and explain precisely why you feel it makes sen=
se to reuse &quot;void&quot; as such a type. Again, I don&#39;t refute that=
 such a type is a valid notion, only that it makes no sense for void to be =
that type as making void such a type does not solve the actual problems we =
are facing. The struct void {}; definition of void makes sensible generic c=
ode work perfectly fine without special-casing void, and I have yet to see =
even one practical example from you regarding how this definition of void w=
ould provide any tangible benefit. Write a simple code example showing the =
benefit and explains why &quot;void&quot; must be this type.</div></div></d=
iv></div>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a113ccf4ae9d920051c84742b--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Tue, 04 Aug 2015 16:40:12 -0700
Raw View
On Tuesday 04 August 2015 23:46:39 'Edward Catmur' via ISO C++ Standard -
Future Proposals wrote:
> I'm not so sure - last I looked you could form tuple<int, void> despite the
> resulting type being non-instantiable i.e. nullary. Such things have their
> uses.

That one is fine, which is a case that would change interpretation with void
becoming instantiable.
--
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/.

.


Author: Paul Fultz II <pfultz28@gmail.com>
Date: Tue, 4 Aug 2015 16:51:36 -0700 (PDT)
Raw View
------=_Part_1900_98113735.1438732296788
Content-Type: multipart/alternative;
 boundary="----=_Part_1901_761080439.1438732296789"

------=_Part_1901_761080439.1438732296789
Content-Type: text/plain; charset=UTF-8



On Tuesday, August 4, 2015 at 6:15:07 PM UTC-5, Matt Calabrese wrote:
>
> On Tue, Aug 4, 2015 at 3:45 PM, Paul Fultz II <pful...@gmail.com
> <javascript:>> wrote:
>>
>> Also, having a type represent zero values is really necessary for
>> completeness, especially if we add variant to the language since `void` is
>> the identity element for variant. Plus, the identity element would allow
>> monadic computations over variant types, which could help with defining
>> DSLs.
>>
>
> I have no doubt that you are trying to make a legitimate point here, but
> please ground this with an example, and explain precisely why you feel it
> makes sense to reuse "void" as such a type. Again, I don't refute that such
> a type is a valid notion, only that it makes no sense for void to be that
> type as making void such a type does not solve the actual problems we are
> facing.
>

It does make sense for `void` to be that type because it represents both
return type for a function that doesn't return anything and it represents
the subtype of all types(such as in `void*`).


> The struct void {}; definition of void makes sensible generic code work
> perfectly fine without special-casing void,
>

But there could be library solutions to help alleviate most of this,
something like this:

struct unit {};
template<class T>
using avoid = typename std::conditional<(std::is_void<T>()), unit, T>::type;


and I have yet to see even one practical example from you regarding how
> this definition of void would provide any tangible benefit. Write a simple
> code example showing the benefit and explains why "void" must be this type.
>

Its not just the benefits. Changing the fundamental type of void to have a
singular value could lead to subtle problems in assumptions made about
code(starting with injecting extra state). As for the benefits of a having
a type to represent zero state is a little beyond me, because I don't write
DSLs, but having tuples and variants form categories would allow them to
form an F-algebra(because I believe they are dual categories) which would
enable evaluation of recursive tree stuctures in a non-recursive fashion.

--

---
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_1901_761080439.1438732296789
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<br><br>On Tuesday, August 4, 2015 at 6:15:07 PM UTC-5, Matt Calabrese wrot=
e:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;b=
order-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div c=
lass=3D"gmail_quote">On Tue, Aug 4, 2015 at 3:45 PM, Paul Fultz II <span di=
r=3D"ltr">&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mail=
to=3D"6yhzwOsCEAAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javasc=
ript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;retur=
n true;">pful...@gmail.com</a>&gt;</span> wrote:<blockquote class=3D"gmail_=
quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1=
ex">Also, having a type represent zero values is really necessary for compl=
eteness, especially if we add variant to the language since `void` is the i=
dentity element for variant. Plus, the identity element would allow monadic=
 computations over variant types, which could help with defining DSLs.<br><=
/blockquote><div><br></div><div>I have no doubt that you are trying to make=
 a legitimate point here, but please ground this with an example, and expla=
in precisely why you feel it makes sense to reuse &quot;void&quot; as such =
a type. Again, I don&#39;t refute that such a type is a valid notion, only =
that it makes no sense for void to be that type as making void such a type =
does not solve the actual problems we are facing. </div></div></div></div><=
/blockquote><div><br>It does make sense for `void` to be that type because =
it represents both return type for a function that doesn&#39;t return anyth=
ing and it represents the subtype of all types(such as in `void*`).<br>=C2=
=A0</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>The struct void {}; definition of void mak=
es sensible generic code work perfectly fine without special-casing void, <=
/div></div></div></div></blockquote><div><br>But there could be library sol=
utions to help alleviate most of this, something like this:<br><br>struct u=
nit {};<br>template&lt;class T&gt;<br>using avoid =3D typename std::conditi=
onal&lt;(std::is_void&lt;T&gt;()), unit, T&gt;::type;<br><br><br></div><blo=
ckquote 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>and I have yet to see even one practical example from=
 you regarding how this definition of void would provide any tangible benef=
it. Write a simple code example showing the benefit and explains why &quot;=
void&quot; must be this type.</div></div></div></div></blockquote><div><br>=
Its not just the benefits. Changing the fundamental type of void to have a =
singular value could lead to subtle problems in assumptions made about code=
(starting with injecting extra state). As for the benefits of a having a ty=
pe to represent zero state is a little beyond me, because I don&#39;t write=
 DSLs, but having tuples and variants form categories would allow them to f=
orm an F-algebra(because I believe they are dual categories) which would en=
able evaluation of recursive tree stuctures in a non-recursive fashion.<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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_1901_761080439.1438732296789--
------=_Part_1900_98113735.1438732296788--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Tue, 4 Aug 2015 16:51:45 -0700
Raw View
--001a113cd41a020ebe051c84f81c
Content-Type: text/plain; charset=UTF-8

On Tue, Aug 4, 2015 at 4:40 PM, Thiago Macieira <thiago@macieira.org> wrote:

> On Tuesday 04 August 2015 23:46:39 'Edward Catmur' via ISO C++ Standard -
> Future Proposals wrote:
> > I'm not so sure - last I looked you could form tuple<int, void> despite
> the
> > resulting type being non-instantiable i.e. nullary. Such things have
> their
> > uses.
>
> That one is fine, which is a case that would change interpretation with
> void
> becoming instantiable.


This can hypothetically change interpretation in some vague sense, but what
code does this break? If people were using such a declaration as a type
list, then that doesn't at all break by this, for example. Even if they
were using void as a special tag type, that's not strictly a breaking
change, it could conceivably not be compatible with new possible uses of
void, but even would be really strange.

Why are we focused on this? If there is an actual problem people are
worried about in code, ground it with an example. This seems like a really
big stretch.

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
ue, Aug 4, 2015 at 4:40 PM, Thiago Macieira <span dir=3D"ltr">&lt;<a href=
=3D"mailto:thiago@macieira.org" target=3D"_blank">thiago@macieira.org</a>&g=
t;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0=
 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Tuesday 04 August 201=
5 23:46:39 &#39;Edward Catmur&#39; via ISO C++ Standard -<br>
<span class=3D"">Future Proposals wrote:<br>
&gt; I&#39;m not so sure - last I looked you could form tuple&lt;int, void&=
gt; despite the<br>
&gt; resulting type being non-instantiable i.e. nullary. Such things have t=
heir<br>
&gt; uses.<br>
<br>
</span>That one is fine, which is a case that would change interpretation w=
ith void<br>
becoming instantiable.</blockquote><div><br></div><div>This can hypothetica=
lly change interpretation in some vague sense, but what code does this brea=
k? If people were using such a declaration as a type list, then that doesn&=
#39;t at all break by this, for example. Even if they were using void as a =
special tag type, that&#39;s not strictly a breaking change, it could conce=
ivably not be compatible with new possible uses of void, but even would be =
really strange.</div><div><br></div><div>Why are we focused on this? If the=
re is an actual problem people are worried about in code, ground it with an=
 example. This seems like a really big stretch.</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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a113cd41a020ebe051c84f81c--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Tue, 4 Aug 2015 17:28:12 -0700
Raw View
--089e01634d7e5a3b15051c857a39
Content-Type: text/plain; charset=UTF-8

On Tue, Aug 4, 2015 at 4:51 PM, Paul Fultz II <pfultz28@gmail.com> wrote:

> On Tuesday, August 4, 2015 at 6:15:07 PM UTC-5, Matt Calabrese wrote:
>>
>> On Tue, Aug 4, 2015 at 3:45 PM, Paul Fultz II <pful...@gmail.com> wrote:
>>>
>>> Also, having a type represent zero values is really necessary for
>>> completeness, especially if we add variant to the language since `void` is
>>> the identity element for variant. Plus, the identity element would allow
>>> monadic computations over variant types, which could help with defining
>>> DSLs.
>>>
>>
>> I have no doubt that you are trying to make a legitimate point here, but
>> please ground this with an example, and explain precisely why you feel it
>> makes sense to reuse "void" as such a type. Again, I don't refute that such
>> a type is a valid notion, only that it makes no sense for void to be that
>> type as making void such a type does not solve the actual problems we are
>> facing.
>>
>
> It does make sense for `void` to be that type because it represents both
> return type for a function that doesn't return anything and it represents
> the subtype of all types(such as in `void*`).
>

You are missing what I am saying. I understand that you want void to mean
that because it coincides with your personal intuitions of "void", but it
has no actual benefit for specifically the c++ void type to be such a type.
If you want such a type we can make one, but using void for it does not
solve any of the problems that we are trying to solve that exist in actual
code. The reason void makes sense as struct void {}; is because that notion
coincides with how things like return values are used in generic code.
Don't decide what you personally thing void *should* mean a priori based on
intuition and have that direct you. Instead, figure out what definition
benefits the language based on how it is actually used in real code. I've
given a lot of actual examples and you still haven't produced any, but here
is another:

//////////
// Invoke a function, logging the arguments and return value
template <class Log, class Fun, class... P>
auto invoke_and_log(Log& log, Fun&& fun, P&&... args) {
  auto my_log = log.template make_function_log<Fun(args...)>();
  my_log.log_arguments(args...);
  auto result = std::forward<Fun>(fun)(std::forward<P>(args)...);
  my_log.log_success(result);
  return result;
}
//////////

You can write this (untested, sorry if there are typos) and it will "work"
in c++. It, however, will currently fail if fun returns void. Why do you
feel that this is somehow beneficial? If we had an instantiable, regular
void, this would work even if the function returned void. You're still
logging a successful function invocation, and your personal serialization
function for void might be a no-op, but so what? What do you think you are
gaining by clinging to some preconceived notion of what void *ought* to be?
Let usage tell us the definition that benefits the writing of code.

On Tue, Aug 4, 2015 at 4:51 PM, Paul Fultz II <pfultz28@gmail.com> wrote:

> But there could be library solutions to help alleviate most of this,
> something like this:
>
> struct unit {};
> template<class T>
> using avoid = typename std::conditional<(std::is_void<T>()), unit,
> T>::type;
>

We already have to do these kinds of hacks. We are trying to eliminate the
need for them.

On Tue, Aug 4, 2015 at 4:51 PM, Paul Fultz II <pfultz28@gmail.com> wrote:

> Its not just the benefits. Changing the fundamental type of void to have a
> singular value could lead to subtle problems in assumptions made about
> code(starting with injecting extra state).
>

Show. An. Example.

On Tue, Aug 4, 2015 at 4:51 PM, Paul Fultz II <pfultz28@gmail.com> wrote:
>
> As for the benefits of a having a type to represent zero state is a little
> beyond me, because I don't write DSLs, but having tuples and variants form
> categories would allow them to form an F-algebra(because I believe they are
> dual categories) which would enable evaluation of recursive tree stuctures
> in a non-recursive fashion.
>

I do write EDSLs and I deal with variants all of the time, and I don't see
the benefit. Maybe there is a theoretical benefit to having such a type and
I just haven't encountered it, which is why I'd like an example, but it
should also clarify why we need "void" specifically to be that type. Having
void be equivalent to a regular struct with no members solves real problems
when writing generic code, and I've shown many actual examples of that.

--

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

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

<div dir=3D"ltr"><div>On Tue, Aug 4, 2015 at 4:51 PM, Paul Fultz II=C2=A0<s=
pan dir=3D"ltr">&lt;<a href=3D"mailto:pfultz28@gmail.com" target=3D"_blank"=
>pfultz28@gmail.com</a>&gt;</span>=C2=A0wrote:<br><blockquote class=3D"gmai=
l_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-lef=
t-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">On Tuesd=
ay, August 4, 2015 at 6:15:07 PM UTC-5, Matt Calabrese wrote:<span class=3D=
""><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;bord=
er-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:soli=
d;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_quote">On Tue, Aug=
 4, 2015 at 3:45 PM, Paul Fultz II=C2=A0<span dir=3D"ltr">&lt;<a rel=3D"nof=
ollow">pful...@gmail.com</a>&gt;</span>=C2=A0wrote:<blockquote class=3D"gma=
il_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-le=
ft-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Also, h=
aving a type represent zero values is really necessary for completeness, es=
pecially if we add variant to the language since `void` is the identity ele=
ment for variant. Plus, the identity element would allow monadic computatio=
ns over variant types, which could help with defining DSLs.<br></blockquote=
><div><br></div><div>I have no doubt that you are trying to make a legitima=
te point here, but please ground this with an example, and explain precisel=
y why you feel it makes sense to reuse &quot;void&quot; as such a type. Aga=
in, I don&#39;t refute that such a type is a valid notion, only that it mak=
es no sense for void to be that type as making void such a type does not so=
lve the actual problems we are facing.</div></div></div></blockquote></span=
><div><br>It does make sense for `void` to be that type because it represen=
ts both return type for a function that doesn&#39;t return anything and it =
represents the subtype of all types(such as in `void*`).<br></div></blockqu=
ote><div><br></div><div>You are missing what I am saying. I understand that=
 you want void to mean that because it coincides with your personal intuiti=
ons of &quot;void&quot;, but it has no actual benefit for specifically the =
c++ void type to be such a type. If you want such a type we can make one, b=
ut using void for it does not solve any of the problems that we are trying =
to solve that exist in actual code. The reason void makes sense as struct v=
oid {}; is because that notion coincides with how things like return values=
 are used in generic code. Don&#39;t decide what you personally thing void=
=C2=A0<i>should</i>=C2=A0mean a priori based on intuition and have that dir=
ect you. Instead, figure out what definition benefits the language based on=
 how it is actually used in real code. I&#39;ve given a lot of actual examp=
les and you still haven&#39;t produced any, but here is another:</div><div>=
<br></div><div>//////////</div><div>// Invoke a function, logging the argum=
ents and return value</div><div>template &lt;class Log, class Fun, class...=
 P&gt;</div><div>auto invoke_and_log(Log&amp; log, Fun&amp;&amp; fun, P&amp=
;&amp;... args) {</div><div>=C2=A0 auto my_log =3D log.template make_functi=
on_log&lt;Fun(args...)&gt;();</div><div>=C2=A0 my_log.log_arguments(args...=
);</div><div>=C2=A0 auto result =3D std::forward&lt;Fun&gt;(fun)(std::forwa=
rd&lt;P&gt;(args)...);</div><div>=C2=A0 my_log.log_success(result);</div><d=
iv>=C2=A0 return result;</div><div>}</div><div>//////////</div><div><br></d=
iv><div>You can write this (untested, sorry if there are typos) and it will=
 &quot;work&quot; in c++. It, however, will currently fail if fun returns v=
oid. Why do you feel that this is somehow beneficial? If we had an instanti=
able, regular void, this would work even if the function returned void. You=
&#39;re still logging a successful function invocation, and your personal s=
erialization function for void might be a no-op, but so what? What do you t=
hink you are gaining by clinging to some preconceived notion of what void=
=C2=A0<i>ought</i>=C2=A0to be? Let usage tell us the definition that benefi=
ts the writing of code.</div></div><div><br></div><div>On Tue, Aug 4, 2015 =
at 4:51 PM, Paul Fultz II=C2=A0<span dir=3D"ltr">&lt;<a href=3D"mailto:pful=
tz28@gmail.com" target=3D"_blank">pfultz28@gmail.com</a>&gt;</span>=C2=A0wr=
ote:</div><div class=3D"gmail_extra"><div class=3D"gmail_quote"><blockquote=
 class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc soli=
d;padding-left:1ex"><div>But there could be library solutions to help allev=
iate most of this, something like this:<br><br>struct unit {};<br>template&=
lt;class T&gt;<br>using avoid =3D typename std::conditional&lt;(std::is_voi=
d&lt;T&gt;()), unit, T&gt;::type;<br></div></blockquote><div><br></div><div=
>We already have to do these kinds of hacks. We are trying to eliminate the=
 need for them.</div><div><br></div><div>On Tue, Aug 4, 2015 at 4:51 PM, Pa=
ul Fultz II=C2=A0<span dir=3D"ltr">&lt;<a href=3D"mailto:pfultz28@gmail.com=
" target=3D"_blank">pfultz28@gmail.com</a>&gt;</span>=C2=A0wrote:<br></div>=
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div>Its not just the benefits. Changing the=
 fundamental type of void to have a singular value could lead to subtle pro=
blems in assumptions made about code(starting with injecting extra state).<=
/div></blockquote><div><br></div><div>Show. An. Example.</div><div><br></di=
v>On Tue, Aug 4, 2015 at 4:51 PM, Paul Fultz II=C2=A0<span dir=3D"ltr">&lt;=
<a href=3D"mailto:pfultz28@gmail.com" target=3D"_blank">pfultz28@gmail.com<=
/a>&gt;</span>=C2=A0wrote:<blockquote class=3D"gmail_quote" style=3D"margin=
:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div> As for the b=
enefits of a having a type to represent zero state is a little beyond me, b=
ecause I don&#39;t write DSLs, but having tuples and variants form categori=
es would allow them to form an F-algebra(because I believe they are dual ca=
tegories) which would enable evaluation of recursive tree stuctures in a no=
n-recursive fashion.<br></div></blockquote><div><br></div><div>I do write E=
DSLs and I deal with variants all of the time, and I don&#39;t see the bene=
fit. Maybe there is a theoretical benefit to having such a type and I just =
haven&#39;t encountered it, which is why I&#39;d like an example, but it sh=
ould also clarify why we need &quot;void&quot; specifically to be that type=
.. Having void be equivalent to a regular struct with no members solves real=
 problems when writing generic code, and I&#39;ve shown many actual example=
s of that.</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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--089e01634d7e5a3b15051c857a39--

.


Author: Roland Bock <rbock@eudoxos.de>
Date: Wed, 05 Aug 2015 09:42:24 +0200
Raw View
This is a multi-part message in MIME format.
--------------090308090300060702030208
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On 2015-08-04 19:34, Miro Knejp wrote:
>
>> On 04 Aug 2015, at 17:32 , Paul Fultz II <pfultz28@gmail.com
>> <mailto:pfultz28@gmail.com>> wrote:
>>
>>
>>
>> On Tuesday, August 4, 2015 at 10:13:07 AM UTC-5, Zach Laine wrote:
>>
>>     On Tue, Aug 4, 2015 at 9:57 AM, Paul Fultz II <pful...@gmail.com
>>     <javascript:>> wrote:
>>
>>
>>         On Tuesday, August 4, 2015 at 4:00:41 AM UTC-5, Bengt
>>         Gustafsson wrote:
>>
>>             How about just defining that void behaves like an empty
>>             struct? This avoids us having to discuss every particular
>>             case. There are still the potentials for code breakage
>>             with tricky SFINAE but I don't see how that can ever be
>>             avoided if we change the behaviour of void at all. Note:
>>             I don't mean that void should BE an empty struct in that
>>             you can inherit from it, but that it acts like one when
>>             used in code.
>>
>>         =20
>>         But having void act like an empty struct, then it becomes a
>>         type with one value. However, `void` should mean a type with
>>         zero values(like a function that doesn't return anything). Of
>>         course, changing `void` from having zero values to one value
>>         could break a lot of assumptions made about code. I think its
>>         a bad idea. For some generic code, it may be safe to assume
>>         void as having one value instead of zero, but it would be
>>         better to use a library solution for this instead of baking
>>         in potential unsafe type assumptions into the language.
>>
>>
>>     Again, I don't see the one value you mention.  Please point to
>>     the value below:
>>
>>     struct foo
>>     {
>>     };
>>
>>     Where is it?  Objects of type "foo" have an address, but no
>>     value, right?  What am I missing?=20
>>
>>
>>
>> Its `foo()`. Thats the one value. You can assign it to a variable:
>
> Which is the very definition of a unit type. Technically they are
> indistinguishable. What changes that in C++ is the fact that we can
> assign every object a memory address and therefore give every instance
> an *identity*. One cannot write a meaningful operator=3D=3D that can
> distinguish two foo operands without taking their address, but at that
> point we=E2=80=99re comparing identities, not states/values.
>
> @Zach:
> Regarding
> void: https://en.wikipedia.org/wiki/Unit_type#Void_type_as_unit_type

Ok, so that page says:

In C, C++, C#, and Java, void expresses the empty type. The unit type in
C would be struct {}, but an empty struct is forbidden by the C language
specification .


But if we go all Wikipedia, then also add this page here:

https://en.wikipedia.org/wiki/Bottom_type (aka empty type)
In type theory, a theory within mathematical logic, the bottom type is
the type that has no values. It is also called the zero or empty type.
The bottom type is sometimes confused with the /so-called "void type",
which is actually a unit type/, albeit one with no defined operations.

So Wikipedia says:

  * void is the bottom type (no value)
  * void is a unit type (exactly one value)

Wikipedia contradicts itself, thus it cannot really be used to decide. ;-)

I guess that is where most of the confusion in this thread arises from.
Some want to interpret void as the value-less bottom type, others want
to interpret void as a unit type (exactly one value).

Thus, when making statement about how void should behave, you should
state whether you are in the "bottom type" or in the "unit type" fraction.


As of now, I am a member of the "unit type" fraction: void does have a
value which - for instance - says that a function has finished
regularly, in contrast to not returning at all, throwing an exception,
or aborting the program.


Cheers,

Roland

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

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

<html>
  <head>
    <meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Type=
">
  </head>
  <body bgcolor=3D"#FFFFFF" text=3D"#000000">
    <div class=3D"moz-cite-prefix">On 2015-08-04 19:34, Miro Knejp wrote:<b=
r>
    </div>
    <blockquote
      cite=3D"mid:ED5B9F62-2757-4637-938E-5B8550C3940A@gmail.com"
      type=3D"cite">
      <meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dutf=
-8">
      <br class=3D"">
      <div>
        <blockquote type=3D"cite" class=3D"">
          <div class=3D"">On 04 Aug 2015, at 17:32 , Paul Fultz II &lt;<a
              moz-do-not-send=3D"true" href=3D"mailto:pfultz28@gmail.com"
              class=3D"">pfultz28@gmail.com</a>&gt; wrote:</div>
          <br class=3D"Apple-interchange-newline">
          <div class=3D""><br class=3D"">
            <br class=3D"">
            On Tuesday, August 4, 2015 at 10:13:07 AM UTC-5, Zach Laine
            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" class=3D"">
                <div class=3D"">
                  <div class=3D"gmail_quote">On Tue, Aug 4, 2015 at 9:57
                    AM, Paul Fultz II <span dir=3D"ltr" class=3D"">&lt;<a
                        moz-do-not-send=3D"true" href=3D"javascript:"
                        target=3D"_blank"
                        gdf-obfuscated-mailto=3D"HzaQM57oDwAJ"
                        rel=3D"nofollow"
                        onmousedown=3D"this.href=3D'javascript:';return
                        true;" onclick=3D"this.href=3D'javascript:';return
                        true;" class=3D"">pful...@gmail.com</a>&gt;</span>
                    wrote:<br class=3D"">
                    <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0
                      .8ex;border-left:1px #ccc solid;padding-left:1ex">
                      <div dir=3D"ltr" class=3D""><br class=3D"">
                        On Tuesday, August 4, 2015 at 4:00:41 AM UTC-5,
                        Bengt Gustafsson wrote:
                        <blockquote class=3D"gmail_quote"
                          style=3D"margin:0;margin-left:0.8ex;border-left:1=
px
                          #ccc solid;padding-left:1ex">
                          <div dir=3D"ltr" class=3D"">How about just
                            defining that void behaves like an empty
                            struct? This avoids us having to discuss
                            every particular case. There are still the
                            potentials for code breakage with tricky
                            SFINAE but I don't see how that can ever be
                            avoided if we change the behaviour of void
                            at all. Note: I don't mean that void should
                            BE an empty struct in that you can inherit
                            from it, but that it acts like one when used
                            in code.<br class=3D"">
                          </div>
                        </blockquote>
                        <div class=3D"">=C2=A0<br class=3D"">
                          But having void act like an empty struct, then
                          it becomes a type with one value. However,
                          `void` should mean a type with zero
                          values(like a function that doesn't return
                          anything). Of course, changing `void` from
                          having zero values to one value could break a
                          lot of assumptions made about code. I think
                          its a bad idea. For some generic code, it may
                          be safe to assume void as having one value
                          instead of zero, but it would be better to use
                          a library solution for this instead of baking
                          in potential unsafe type assumptions into the
                          language.</div>
                      </div>
                    </blockquote>
                    <div class=3D""><br class=3D"">
                    </div>
                    <div class=3D"">Again, I don't see the one value you
                      mention.=C2=A0 Please point to the value below:</div>
                    <div class=3D""><br class=3D"">
                    </div>
                    <div class=3D"">struct foo</div>
                    <div class=3D"">{</div>
                    <div class=3D"">};</div>
                    <div class=3D""><br class=3D"">
                    </div>
                    <div class=3D"">Where is it?=C2=A0 Objects of type "foo=
"
                      have an address, but no value, right?=C2=A0 What am I
                      missing?=C2=A0</div>
                  </div>
                </div>
              </div>
            </blockquote>
            <div class=3D""><br class=3D"">
              <br class=3D"">
              Its `foo()`. Thats the one value. You can assign it to a
              variable:<br class=3D"">
            </div>
          </div>
        </blockquote>
        <div><br class=3D"">
        </div>
        <div>Which is the very definition of a unit type. Technically
          they are indistinguishable. What changes that in C++ is the
          fact that we can assign every object a memory address and
          therefore give every instance an *identity*. One cannot write
          a meaningful operator=3D=3D that can distinguish two foo operands
          without taking their address, but at that point we=E2=80=99re
          comparing identities, not states/values.</div>
        <div><br class=3D"">
        </div>
        <div>@Zach:</div>
        <div>Regarding void:=C2=A0<a moz-do-not-send=3D"true"
            href=3D"https://en.wikipedia.org/wiki/Unit_type#Void_type_as_un=
it_type"
            class=3D"">https://en.wikipedia.org/wiki/Unit_type#Void_type_as=
_unit_type</a></div>
      </div>
    </blockquote>
    <br>
    Ok, so that page says:<br>
    <br>
    In C, C++, C#, and Java, void expresses the empty type. The unit
    type in C would be struct {}, but an empty struct is forbidden by
    the C language specification
    <meta http-equiv=3D"content-type" content=3D"text/html; charset=3Dutf-8=
">
    .<br>
    <meta http-equiv=3D"content-type" content=3D"text/html; charset=3Dutf-8=
">
    <br>
    <br>
    But if we go all Wikipedia, then also add this page here:<br>
    <br>
    <a class=3D"moz-txt-link-freetext" href=3D"https://en.wikipedia.org/wik=
i/Bottom_type">https://en.wikipedia.org/wiki/Bottom_type</a> (aka empty typ=
e)<br>
    In type theory, a theory within mathematical logic, the bottom type
    is the type that has no values. It is also called the zero or empty
    type. The bottom type is sometimes confused with the <i>so-called
      "void type", which is actually a unit type</i>, albeit one with no
    defined operations.<br>
    <br>
    So Wikipedia says:<br>
    <br>
    =C2=A0 * void is the bottom type (no value)<br>
    =C2=A0 * void is a unit type (exactly one value)<br>
    <br>
    Wikipedia contradicts itself, thus it cannot really be used to
    decide. ;-)<br>
    <br>
    I guess that is where most of the confusion in this thread arises
    from. Some want to interpret void as the value-less bottom type,
    others want to interpret void as a unit type (exactly one value).<br>
    <br>
    Thus, when making statement about how void should behave, you should
    state whether you are in the "bottom type" or in the "unit type"
    fraction.<br>
    <br>
    <br>
    As of now, I am a member of the "unit type" fraction: void does have
    a value which - for instance - says that a function has finished
    regularly, in contrast to not returning at all, throwing an
    exception, or aborting the program.<br>
    <br>
    <br>
    Cheers,<br>
    <br>
    Roland<br>
  </body>
</html>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--------------090308090300060702030208--

.


Author: Miro Knejp <miro.knejp@gmail.com>
Date: Wed, 5 Aug 2015 11:58:25 +0200
Raw View
--Apple-Mail=_2E58726E-A112-4561-9387-42B42F052ABC
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8


> On 05 Aug 2015, at 09:42 , Roland Bock <rbock@eudoxos.de> wrote:
>=20
> Ok, so that page says:
>=20
> In C, C++, C#, and Java, void expresses the empty type. The unit type in =
C would be struct {}, but an empty struct is forbidden by the C language sp=
ecification .
>=20
>=20
> But if we go all Wikipedia, then also add this page here:
>=20
> https://en.wikipedia.org/wiki/Bottom_type <https://en.wikipedia.org/wiki/=
Bottom_type> (aka empty type)
> In type theory, a theory within mathematical logic, the bottom type is th=
e type that has no values. It is also called the zero or empty type. The bo=
ttom type is sometimes confused with the so-called "void type", which is ac=
tually a unit type, albeit one with no defined operations.
>=20
> So Wikipedia says:
>=20
>   * void is the bottom type (no value)
>   * void is a unit type (exactly one value)
>=20
> Wikipedia contradicts itself, thus it cannot really be used to decide. ;-=
)
>=20
> I guess that is where most of the confusion in this thread arises from. S=
ome want to interpret void as the value-less bottom type, others want to in=
terpret void as a unit type (exactly one value).
>=20
> Thus, when making statement about how void should behave, you should stat=
e whether you are in the "bottom type" or in the "unit type" fraction.
>=20
>=20
> As of now, I am a member of the "unit type" fraction: void does have a va=
lue which - for instance - says that a function has finished regularly, in =
contrast to not returning at all, throwing an exception, or aborting the pr=
ogram.

Yay for contradictions. I=E2=80=99d say that void as it stands in C++ now i=
s somewhere between the bottom and unit type. It is really neither of them:

- Functions marked with void do return to the caller but shouldn=E2=80=99t =
if void was the bottom type
- Functions marked with void or taking void do not take or return values, b=
ut they would take or return the singular unit value if void were a unit ty=
pe

In a perfect world C++ would have a builtin unit type and a builtin bottom =
type (so everyone would use those by default instead of rolling their own),=
 right now it really has neither. Considering the status quo void would be =
much more useful in practice as a unit type. The vast majority of functions=
 do terminate so the need for a real bottom type is minuscule.

I don=E2=80=99t think you=E2=80=99d have to change the ABI to support void =
as a unit type. The compiler can simply pretend that it=E2=80=99s passing a=
 unit value to nullary external functions and it can make a new unit value =
out of thin air for functions returning void. Right now you cannot have voi=
d in the middle of the argument list so there is no possibility in ABI brea=
kage for existing functions. Once the void unit type is properly mangled ne=
w functions can have it anywhere in the argument list.

The problem I still see is that decltype(foo(T())) can already be used to f=
ilter out void in SFINAE so if it were to suddenly be well-formed for T=3Dv=
oid that can change the behavior of existing code. Where is that damn ship =
sailing to anyways, someone make it come back.

--=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=_2E58726E-A112-4561-9387-42B42F052ABC
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 05 Aug 2015, at 0=
9:42 , Roland Bock &lt;<a href=3D"mailto:rbock@eudoxos.de" class=3D"">rbock=
@eudoxos.de</a>&gt; wrote:</div><br class=3D"Apple-interchange-newline"><di=
v class=3D"">
 =20
    <meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Type=
" class=3D"">
 =20
  <div bgcolor=3D"#FFFFFF" text=3D"#000000" class=3D"">
    <div class=3D"moz-cite-prefix">Ok, so that page says:</div>
    <br class=3D"">
    In C, C++, C#, and Java, void expresses the empty type. The unit
    type in C would be struct {}, but an empty struct is forbidden by
    the C language specification
    <meta http-equiv=3D"content-type" content=3D"text/html; charset=3Dutf-8=
" class=3D"">
    .<br class=3D"">
    <meta http-equiv=3D"content-type" content=3D"text/html; charset=3Dutf-8=
" class=3D"">
    <br class=3D"">
    <br class=3D"">
    But if we go all Wikipedia, then also add this page here:<br class=3D""=
>
    <br class=3D"">
    <a class=3D"moz-txt-link-freetext" href=3D"https://en.wikipedia.org/wik=
i/Bottom_type">https://en.wikipedia.org/wiki/Bottom_type</a> (aka empty typ=
e)<br class=3D"">
    In type theory, a theory within mathematical logic, the bottom type
    is the type that has no values. It is also called the zero or empty
    type. The bottom type is sometimes confused with the <i class=3D"">so-c=
alled
      "void type", which is actually a unit type</i>, albeit one with no
    defined operations.<br class=3D"">
    <br class=3D"">
    So Wikipedia says:<br class=3D"">
    <br class=3D"">
    &nbsp; * void is the bottom type (no value)<br class=3D"">
    &nbsp; * void is a unit type (exactly one value)<br class=3D"">
    <br class=3D"">
    Wikipedia contradicts itself, thus it cannot really be used to
    decide. ;-)<br class=3D"">
    <br class=3D"">
    I guess that is where most of the confusion in this thread arises
    from. Some want to interpret void as the value-less bottom type,
    others want to interpret void as a unit type (exactly one value).<br cl=
ass=3D"">
    <br class=3D"">
    Thus, when making statement about how void should behave, you should
    state whether you are in the "bottom type" or in the "unit type"
    fraction.<br class=3D"">
    <br class=3D"">
    <br class=3D"">
    As of now, I am a member of the "unit type" fraction: void does have
    a value which - for instance - says that a function has finished
    regularly, in contrast to not returning at all, throwing an
    exception, or aborting the program.<br class=3D""></div></div></blockqu=
ote></div><br class=3D""><div class=3D"">Yay for contradictions. I=E2=80=99=
d say that void as it stands in C++ now is somewhere between the bottom and=
 unit type. It is really neither of them:</div><div class=3D""><br class=3D=
""></div><div class=3D"">- Functions marked with void do return to the call=
er but shouldn=E2=80=99t if void was the bottom type</div><div class=3D"">-=
 Functions marked with void or taking void do not take or return values, bu=
t they would take or return the singular unit value if void were a unit typ=
e</div><div class=3D""><br class=3D""></div><div class=3D"">In a perfect wo=
rld C++ would have a builtin unit type and a builtin bottom type (so everyo=
ne would use those by default instead of rolling their own), right now it r=
eally has neither. Considering the status quo void would be much more usefu=
l in practice as a unit type. The vast majority of functions do terminate s=
o the need for a real bottom type is minuscule.</div><div class=3D""><br cl=
ass=3D""></div><div class=3D"">I don=E2=80=99t think you=E2=80=99d have to =
change the ABI to support void as a unit type. The compiler can simply pret=
end that it=E2=80=99s passing a unit value to nullary external functions an=
d it can make a new unit value out of thin air for functions returning void=
.. Right now you cannot have void in the middle of the argument list so ther=
e is no possibility in ABI breakage for existing functions. Once the void u=
nit type is properly mangled new functions can have it anywhere in the argu=
ment list.</div><div class=3D""><br class=3D""></div><div class=3D"">The pr=
oblem I still see is that decltype(foo(T())) can already be used to filter =
out void in SFINAE so if it were to suddenly be well-formed for T=3Dvoid th=
at can change the behavior of existing code. Where is that damn ship sailin=
g to anyways, someone make it come back.</div><div class=3D""><br class=3D"=
"></div></body></html>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_2E58726E-A112-4561-9387-42B42F052ABC--

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Wed, 05 Aug 2015 09:54:02 -0400
Raw View
On 2015-08-04 19:15, 'Matt Calabrese' via ISO C++ Standard - Future
Proposals wrote:
> On Tue, Aug 4, 2015 at 3:45 PM, Paul Fultz II <pfultz28@gmail.com> wrote:
>> Also, having a type represent zero values is really necessary for
>> completeness, especially if we add variant to the language since `void` is
>> the identity element for variant.
>
> I have no doubt that you are trying to make a legitimate point here, but
> please ground this with an example, and explain precisely why you feel it
> makes sense to reuse "void" as such a type.

....because that's how it is *already* used?

I've been rather half following the discussion, albeit with some
concern. I'm certainly not against making it easier to use 'void' in
generic programming, however I think it's critical to keep in mind that
the first requirement be that the following program does not change in
meaning:

    void foo();

    int main()
    {
        foo();
        return 0;
    }

    void foo(void)
    {
        return;
    }

(Note in particular that making void a regular type - i.e. 'struct
void{}' - WILL BREAK THIS! NOT ACCEPTABLE!)

Rather (without getting into some of the more esoteric template
questions), it seems like the following should be made legal:

    // allow void declaration; initialization is irrelevant
    void x;

    // allow void assignment; exactly equivalent to:
    //     (void)foo(); void y;
    void y = foo();

    // allow deduction from void
    auto z = x;

    // allow passing void declaration as argument to function
    // taking zero arguments
    foo(x);

    // allow comparing void declarations (see also relational operators
    // for Python's 'None')
    assert(x == y);
    assert(!(x != y));

    // (optional) "allow" taking the address of a void declaration
    auto p = &x;
    assert(p == nullptr); // ...but 'x' has no storage

I would consider any proposal that doesn't provide at least the above a
waste of time, if not a step in the wrong direction. In particular, I'm
concerned that there doesn't seem to be enough discussion how to
preserve calling a function with argument list "(void)" with no
arguments, or calling a function taking no arguments with a single
argument of type 'void'. These are required to add benefit without
breaking existing code, and they necessitate continuing to handle 'void'
specially.

'void' is the zero-value type and SHOULD be handled specially! The
objective here is to also allow it to be used in generic programming
with less specialization.

On 2015-08-04 20:28, 'Matt Calabrese' via ISO C++ Standard - Future
Proposals wrote:
> // Invoke a function, logging the arguments and return value
> template <class Log, class Fun, class... P>
> auto invoke_and_log(Log& log, Fun&& fun, P&&... args) {
>   auto my_log = log.template make_function_log<Fun(args...)>();
>   my_log.log_arguments(args...);
>   auto result = std::forward<Fun>(fun)(std::forward<P>(args)...);
>   my_log.log_success(result);
>   return result;
> }

This will work, with the above, if 'Log::log_success(void)' exists. It's
not necessary for this example to make 'void' a regular type.

> If we had an instantiable, regular void, this would work even if the
> function returned void.

"Instantiable" may or may not be correct terminology here. In the 'void'
case, 'result' names an entity, but no storage is ever associated with
it; basically, 'void x' is just telling the compiler to allow you to
write 'x' again somewhere a value is not actually needed, e.g. 'foo(x)'
for 'void foo()' or 'return x' in a void function.

--
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: j4cbo@dropbox.com
Date: Wed, 5 Aug 2015 10:24:08 -0700 (PDT)
Raw View
------=_Part_48_1852296413.1438795448498
Content-Type: multipart/alternative;
 boundary="----=_Part_49_1285458709.1438795448499"

------=_Part_49_1285458709.1438795448499
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Wednesday, August 5, 2015 at 2:58:31 AM UTC-7, Miro Knejp wrote:
>
> Yay for contradictions. I=E2=80=99d say that void as it stands in C++ now=
 is=20
> somewhere between the bottom and unit type. It is really neither of them:
>
> - Functions marked with void do return to the caller but shouldn=E2=80=99=
t if void=20
> was the bottom type
> - Functions marked with void or taking void do not take or return values,=
=20
> but they would take or return the singular unit value if void were a unit=
=20
> type
>

The behavior of pointer-to-void makes void seem a lot like bottom, but I=20
think in general it's much closer to unit. "Does not return a value" is=20
tricky phrasing, since in the type theory where 'bottom' and 'unit' come=20
from, "does not return a value" means "does not return at all". And there=
=20
are already some contexts in which void seems very unit-like:

void f() { return void(); } // this is already legal
void g() { return f(); } // so is this

As for parameters, I think that debate belongs with the tuple /=20
multiple-return-value discussion. (You could even argue that 'f()' looks a=
=20
lot like passing a 0-tuple to f, but that's stretching the analogy pretty=
=20
far...)

--=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_49_1285458709.1438795448499
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Wednesday, August 5, 2015 at 2:58:31 AM UTC-7, Miro Kne=
jp wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div style=3D"word-wr=
ap:break-word"><div>Yay for contradictions. I=E2=80=99d say that void as it=
 stands in C++ now is somewhere between the bottom and unit type. It is rea=
lly neither of them:</div><div><br></div><div>- Functions marked with void =
do return to the caller but shouldn=E2=80=99t if void was the bottom type</=
div><div>- Functions marked with void or taking void do not take or return =
values, but they would take or return the singular unit value if void were =
a unit type</div></div></blockquote><div><br></div><div>The behavior of poi=
nter-to-void makes void seem a lot like bottom, but I think in general it&#=
39;s much closer to unit. &quot;Does not return a value&quot; is tricky phr=
asing, since in the type theory where &#39;bottom&#39; and &#39;unit&#39; c=
ome from, &quot;does not return a value&quot; means &quot;does not return a=
t all&quot;. And there are already some contexts in which void seems very u=
nit-like:</div><div><br></div><div><div>void f() { return void(); } // this=
 is already legal</div><div>void g() { return f(); } // so is this</div></d=
iv><div><br></div><div>As for parameters, I think that debate belongs with =
the tuple / multiple-return-value discussion. (You could even argue that &#=
39;f()&#39; looks a lot like passing a 0-tuple to f, but that&#39;s stretch=
ing the analogy pretty far...)</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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_49_1285458709.1438795448499--
------=_Part_48_1852296413.1438795448498--

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Wed, 05 Aug 2015 13:53:31 -0400
Raw View
On 2015-08-05 13:24, j4cbo@dropbox.com wrote:
> You could even argue that 'f()' looks a lot like passing a 0-tuple to
> f, but that's stretching the analogy pretty far...

You mean like this?

    $ python
    >>> def foo(*args):
    ...   print len(args)
    ...
    >>> foo()
    0

;-)

Or this?

    $ cat arglist.cpp
    #include <cstdio>

    template <typename... Args>
    void foo(Args const&... args)
    {
        printf("%s called with %d arguments\n",
        __func__, sizeof...(Args));
    }

    int main()
    {
        foo();
        return 0;
    }

    $ g++ -std=c++11 arglist.cpp && ./a.out
    foo called with 0 arguments

--
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: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Wed, 5 Aug 2015 11:31:00 -0700
Raw View
--047d7bd7648eca2a12051c949a6e
Content-Type: text/plain; charset=UTF-8

On Wed, Aug 5, 2015 at 6:54 AM, Matthew Woehlke <mwoehlke.floss@gmail.com>
wrote:

> On 2015-08-04 19:15, 'Matt Calabrese' via ISO C++ Standard - Future
> Proposals wrote:
> > On Tue, Aug 4, 2015 at 3:45 PM, Paul Fultz II <pfultz28@gmail.com>
> wrote:
> >> Also, having a type represent zero values is really necessary for
> >> completeness, especially if we add variant to the language since `void`
> is
> >> the identity element for variant.
> >
> > I have no doubt that you are trying to make a legitimate point here, but
> > please ground this with an example, and explain precisely why you feel it
> > makes sense to reuse "void" as such a type.
>
> ...because that's how it is *already* used?


No, it's really not. Even in the language as it is today it is
inconsistently used as a unit type. It's just incomplete. As someone
already mentioned, a true lack of result would be more accurately
represented by a function not returning at all (I.E. a [[noreturn]]
function that terminates). That is not what a void return type means in C
nor in C++. Similarly, in C++, it is already legal to return a void
expression in the return statement of a function that returns void. Here we
appear to be treating it as a value and copying it around, as that's what
such returning means with all other types. These certainly point to void
simply being a partially specified unit type rather than something else.
Not that any of this matters, because we are not trying to put a label on
what void in C++ currently is, but rather, we are trying to figure out what
definition of void would most benefit the language in the future. Instead
of niggling over possible interpretations of the words "void" or
"emptiness," we should be looking at what definition of void with respect
to C++ actually aids in developing software. We have actual usage and
tangible examples for why it is extremely useful for void to simply be a
regular type, regardless of whatever label you want to give it. I have seen
NO tangible examples from the opposing crowd for why it should be something
less.

As an aside, in C, when void was specified, a full definition of void
didn't really matter much because the use-cases for void being regular come
about when writing more abstract, generic code, which is less common in C
outside of sophisticated macros. It doesn't really matter much in C because
the uses for a complete void type don't usually come up in practice.
Because of this, I'd personally argue that the nature of void as an
incomplete type seems much more incidental due to there not having been
obvious use-cases for it at the time (we have use-cases now). Even if the
choice was NOT incidental, there are very strong reasons that show that it
is much more beneficial to treat it as a regular type, so regardless of how
you want to interpret its current meaning or reason for being, there are
very clear benefits to making it complete and regular. You are only hurting
progress and people writing actual code if you ignore that.

On Wed, Aug 5, 2015 at 6:54 AM, Matthew Woehlke <mwoehlke.floss@gmail.com>
 wrote:

>     void foo();
>
>     int main()
>     {
>         foo();
>         return 0;
>     }
>
>     void foo(void)
>     {
>         return;
>     }
>
> (Note in particular that making void a regular type - i.e. 'struct
> void{}' - WILL BREAK THIS! NOT ACCEPTABLE!)
>

No, you just specify that "return;" is shorthand for "return void();". No
one is suggesting that we break code like this. I don't think anyone in
this thread was under that assumption. This isn't really much of a change,
since you don't have to write "return;", but rather, you can already, in
valid C++, write "return g();", where "g" is another function that returns
void. It's more just syntactic sugar. Of note, if you really wanted to, you
could even generalize that notion to mean that "return;" is just syntactic
sugar for "return T();" where T is the return value of the function (I'm
not suggesting that we do this in the language, I'm just using it as an
example of its interpretation as syntactic sugar).

On Wed, Aug 5, 2015 at 6:54 AM, Matthew Woehlke <mwoehlke.floss@gmail.com>
 wrote:

> Rather (without getting into some of the more esoteric template
> questions), it seems like the following should be made legal:
>
>     // allow void declaration; initialization is irrelevant
>     void x;
>
>     // allow void assignment; exactly equivalent to:
>     //     (void)foo(); void y;
>     void y = foo();
>
>     // allow deduction from void
>     auto z = x;
>
>     // allow passing void declaration as argument to function
>     // taking zero arguments
>     foo(x);
>
>     // allow comparing void declarations (see also relational operators
>     // for Python's 'None')
>     assert(x == y);
>     assert(!(x != y));
>
>     // (optional) "allow" taking the address of a void declaration
>     auto p = &x;
>     assert(p == nullptr); // ...but 'x' has no storage
>

This is just silly. What are you gaining by arbitrarily limiting to these
operations like this and defining them in this manner? Please refer to the
many actual examples that I've accumulated throughout this thread
(including why you shouldn't have argument collapsing) and the 0 examples
that you have provided regarding the benefits of your representation for
void in C++. Unless you show why in practice what you are proposing
improves over void simply being a regular type, and actually succeeds at
removing the special casing of void in generic programming, then the
suggested behavior is providing no visible worth. So far you have done
neither. Don't dictate what void "should" be. Deduce what void should be
based on what makes it easy to write meaningful and powerful code.

On Wed, Aug 5, 2015 at 6:54 AM, Matthew Woehlke <mwoehlke.floss@gmail.com>
 wrote:

> In particular, I'm
> concerned that there doesn't seem to be enough discussion how to
> preserve calling a function with argument list "(void)" with no
> arguments, or calling a function taking no arguments with a single
> argument of type 'void'.


??? What is "enough." This was already talked about pretty extensively. It
is not proposed that void foo(void) {} changes meaning, because that would
be a huge breaking change. There have been at least 3 suggestions presented
in 3 different replies for how to actually represent a unary function
taking void.

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On W=
ed, Aug 5, 2015 at 6:54 AM, Matthew Woehlke <span dir=3D"ltr">&lt;<a href=
=3D"mailto:mwoehlke.floss@gmail.com" target=3D"_blank">mwoehlke.floss@gmail=
..com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On 2015-08-04 =
19:15, &#39;Matt Calabrese&#39; via ISO C++ Standard - Future<br>
<span class=3D"">Proposals wrote:<br>
&gt; On Tue, Aug 4, 2015 at 3:45 PM, Paul Fultz II &lt;<a href=3D"mailto:pf=
ultz28@gmail.com">pfultz28@gmail.com</a>&gt; wrote:<br>
&gt;&gt; Also, having a type represent zero values is really necessary for<=
br>
&gt;&gt; completeness, especially if we add variant to the language since `=
void` is<br>
&gt;&gt; the identity element for variant.<br>
&gt;<br>
</span><span class=3D"">&gt; I have no doubt that you are trying to make a =
legitimate point here, but<br>
&gt; please ground this with an example, and explain precisely why you feel=
 it<br>
&gt; makes sense to reuse &quot;void&quot; as such a type.<br>
<br>
</span>...because that&#39;s how it is *already* used?</blockquote><div><br=
></div><div>No, it&#39;s really not. Even in the language as it is today it=
 is inconsistently used as a unit type. It&#39;s just incomplete. As someon=
e already mentioned, a true lack of result would be more accurately represe=
nted by a function not returning at all (I.E. a [[noreturn]] function that =
terminates). That is not what a void return type means in C nor in C++. Sim=
ilarly, in C++, it is already legal to return a void expression in the retu=
rn statement of a function that returns void. Here we appear to be treating=
 it as a value and copying it around, as that&#39;s what such returning mea=
ns with all other types. These certainly point to void simply being a parti=
ally specified unit type rather than something else. Not that any of this m=
atters, because we are not trying to put a label on what void in C++ curren=
tly is, but rather, we are trying to figure out what definition of void wou=
ld most benefit the language in the future. Instead of niggling over possib=
le interpretations of the words &quot;void&quot; or &quot;emptiness,&quot; =
we should be looking at what definition of void with respect to C++ actuall=
y aids in developing software. We have actual usage and tangible examples f=
or why it is extremely useful for void to simply be a regular type, regardl=
ess of whatever label you want to give it. I have seen NO tangible examples=
 from the opposing crowd for why it should be something less.</div><div><br=
></div><div>As an aside, in C, when void was specified, a full definition o=
f void didn&#39;t really matter much because the use-cases for void being r=
egular come about when writing more abstract, generic code, which is less c=
ommon in C outside of sophisticated macros. It doesn&#39;t really matter mu=
ch in C because the uses for a complete void type don&#39;t usually come up=
 in practice. Because of this, I&#39;d personally argue that the nature of =
void as an incomplete type seems much more incidental due to there not havi=
ng been obvious use-cases for it at the time (we have use-cases now). Even =
if the choice was NOT incidental, there are very strong reasons that show t=
hat it is much more beneficial to treat it as a regular type, so regardless=
 of how you want to interpret its current meaning or reason for being, ther=
e are very clear benefits to making it complete and regular. You are only h=
urting progress and people writing actual code if you ignore that.</div><di=
v><br></div><div>On Wed, Aug 5, 2015 at 6:54 AM, Matthew Woehlke=C2=A0<span=
 dir=3D"ltr">&lt;<a href=3D"mailto:mwoehlke.floss@gmail.com" target=3D"_bla=
nk">mwoehlke.floss@gmail.com</a>&gt;</span>=C2=A0wrote:</div><blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;p=
adding-left:1ex">
=C2=A0 =C2=A0 void foo();<br>
<br>
=C2=A0 =C2=A0 int main()<br>
=C2=A0 =C2=A0 {<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 foo();<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 return 0;<br>
=C2=A0 =C2=A0 }<br>
<br>
=C2=A0 =C2=A0 void foo(void)<br>
=C2=A0 =C2=A0 {<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 return;<br>
=C2=A0 =C2=A0 }<br>
<br>
(Note in particular that making void a regular type - i.e. &#39;struct<br>
void{}&#39; - WILL BREAK THIS! NOT ACCEPTABLE!)<br></blockquote><div><br></=
div><div>No, you just specify that &quot;return;&quot; is shorthand for &qu=
ot;return void();&quot;. No one is suggesting that we break code like this.=
 I don&#39;t think anyone in this thread was under that assumption. This is=
n&#39;t really much of a change, since you don&#39;t have to write &quot;re=
turn;&quot;, but rather, you can already, in valid C++, write &quot;return =
g();&quot;, where &quot;g&quot; is another function that returns void. It&#=
39;s more just syntactic sugar. Of note, if you really wanted to, you could=
 even generalize that notion to mean that &quot;return;&quot; is just synta=
ctic sugar for &quot;return T();&quot; where T is the return value of the f=
unction (I&#39;m not suggesting that we do this in the language, I&#39;m ju=
st using it as an example of its interpretation as syntactic sugar).=C2=A0<=
/div><div>=C2=A0</div><div>On Wed, Aug 5, 2015 at 6:54 AM, Matthew Woehlke=
=C2=A0<span dir=3D"ltr">&lt;<a href=3D"mailto:mwoehlke.floss@gmail.com" tar=
get=3D"_blank">mwoehlke.floss@gmail.com</a>&gt;</span>=C2=A0wrote:<br></div=
><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1=
px #ccc solid;padding-left:1ex">Rather (without getting into some of the mo=
re esoteric template<br>
questions), it seems like the following should be made legal:<br>
<br>
=C2=A0 =C2=A0 // allow void declaration; initialization is irrelevant<br>
=C2=A0 =C2=A0 void x;<br>
<br>
=C2=A0 =C2=A0 // allow void assignment; exactly equivalent to:<br>
=C2=A0 =C2=A0 //=C2=A0 =C2=A0 =C2=A0(void)foo(); void y;<br>
=C2=A0 =C2=A0 void y =3D foo();<br>
<br>
=C2=A0 =C2=A0 // allow deduction from void<br>
=C2=A0 =C2=A0 auto z =3D x;<br>
<br>
=C2=A0 =C2=A0 // allow passing void declaration as argument to function<br>
=C2=A0 =C2=A0 // taking zero arguments<br>
=C2=A0 =C2=A0 foo(x);<br>
<br>
=C2=A0 =C2=A0 // allow comparing void declarations (see also relational ope=
rators<br>
=C2=A0 =C2=A0 // for Python&#39;s &#39;None&#39;)<br>
=C2=A0 =C2=A0 assert(x =3D=3D y);<br>
=C2=A0 =C2=A0 assert(!(x !=3D y));<br>
<br>
=C2=A0 =C2=A0 // (optional) &quot;allow&quot; taking the address of a void =
declaration<br>
=C2=A0 =C2=A0 auto p =3D &amp;x;<br>
=C2=A0 =C2=A0 assert(p =3D=3D nullptr); // ...but &#39;x&#39; has no storag=
e<br></blockquote><div><br></div><div>This is just silly. What are you gain=
ing by arbitrarily limiting to these operations like this and defining them=
 in this manner? Please refer to the many actual examples that I&#39;ve acc=
umulated throughout this thread (including why you shouldn&#39;t have argum=
ent collapsing) and the 0 examples that you have provided regarding the ben=
efits of your representation for void in C++. Unless you show why in practi=
ce what you are proposing improves over void simply being a regular type, a=
nd actually succeeds at removing the special casing of void in generic prog=
ramming, then the suggested behavior is providing no visible worth. So far =
you have done neither. Don&#39;t dictate what void &quot;should&quot; be. D=
educe what void should be based on what makes it easy to write meaningful a=
nd powerful code.</div><div>=C2=A0</div><div>On Wed, Aug 5, 2015 at 6:54 AM=
, Matthew Woehlke=C2=A0<span dir=3D"ltr">&lt;<a href=3D"mailto:mwoehlke.flo=
ss@gmail.com" target=3D"_blank">mwoehlke.floss@gmail.com</a>&gt;</span>=C2=
=A0wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 =
..8ex;border-left:1px #ccc solid;padding-left:1ex">In particular, I&#39;m<br=
>
concerned that there doesn&#39;t seem to be enough discussion how to<br>
preserve calling a function with argument list &quot;(void)&quot; with no<b=
r>
arguments, or calling a function taking no arguments with a single<br>
argument of type &#39;void&#39;.</blockquote><div><br></div><div>??? What i=
s &quot;enough.&quot; This was already talked about pretty extensively. It =
is not proposed that void foo(void) {} changes meaning, because that would =
be a huge breaking change. There have been at least 3 suggestions presented=
 in 3 different replies for how to actually represent a unary function taki=
ng void.</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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--047d7bd7648eca2a12051c949a6e--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Wed, 5 Aug 2015 12:03:39 -0700
Raw View
--001a113cd18c87ce8a051c950f40
Content-Type: text/plain; charset=UTF-8

On Wed, Aug 5, 2015 at 11:31 AM, Matt Calabrese <calabrese@google.com>
wrote:
>
> On Wed, Aug 5, 2015 at 6:54 AM, Matthew Woehlke <mwoehlke.floss@gmail.com>
>  wrote:
>
>>     void foo();
>>
>>     int main()
>>     {
>>         foo();
>>         return 0;
>>     }
>>
>>     void foo(void)
>>     {
>>         return;
>>     }
>>
>> (Note in particular that making void a regular type - i.e. 'struct
>> void{}' - WILL BREAK THIS! NOT ACCEPTABLE!)
>
>
> No, you just specify that "return;" is shorthand for "return void();". No
> one is suggesting that we break code like this. I don't think anyone in
> this thread was under that assumption. This isn't really much of a change,
> since you don't have to write "return;", but rather, you can already, in
> valid C++, write "return g();", where "g" is another function that returns
> void. It's more just syntactic sugar. Of note, if you really wanted to, you
> could even generalize that notion to mean that "return;" is just syntactic
> sugar for "return T();" where T is the return value of the function (I'm
> not suggesting that we do this in the language, I'm just using it as an
> example of its interpretation as syntactic sugar).
>

I just looked back and noticed you mean the void foo(); and void(void) {}
difference. I thought you meant the return statement. I went over this
later on in this reply anyway, but as mentioned several times in previous
replies in this very thread, we are not proposing breaking the code that
you've shown. No meaning would change here because the implications would
be too great. Instead, if you are in a place where void is not a dependent
type, it has the current meaning. If dependent, which is where we actually
care about this and where void would not produce a valid function
declaration in C++, it means unary void. If you want to represent a unary
void function in a non-dependent context you'd just use some other syntax,
which is unfortunate, but fine, and doesn't hurt generic code. There have
been multiple suggestions for what that syntax would be.

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On W=
ed, Aug 5, 2015 at 11:31 AM, Matt Calabrese <span dir=3D"ltr">&lt;<a href=
=3D"mailto:calabrese@google.com" target=3D"_blank">calabrese@google.com</a>=
&gt;</span> wrote:<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 clas=
s=3D"gmail_extra"><div class=3D"gmail_quote"><span class=3D""><div>On Wed, =
Aug 5, 2015 at 6:54 AM, Matthew Woehlke=C2=A0<span dir=3D"ltr">&lt;<a href=
=3D"mailto:mwoehlke.floss@gmail.com" target=3D"_blank">mwoehlke.floss@gmail=
..com</a>&gt;</span>=C2=A0wrote:</div><blockquote class=3D"gmail_quote" styl=
e=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
=C2=A0 =C2=A0 void foo();<br>
<br>
=C2=A0 =C2=A0 int main()<br>
=C2=A0 =C2=A0 {<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 foo();<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 return 0;<br>
=C2=A0 =C2=A0 }<br>
<br>
=C2=A0 =C2=A0 void foo(void)<br>
=C2=A0 =C2=A0 {<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 return;<br>
=C2=A0 =C2=A0 }<br>
<br>
(Note in particular that making void a regular type - i.e. &#39;struct<br>
void{}&#39; - WILL BREAK THIS! NOT ACCEPTABLE!)=C2=A0</blockquote></span></=
div></div></div></blockquote><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 class=3D"gmail_extra"><div class=3D"gmail_quote"><span class=3D""><b=
lockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px =
#ccc solid;padding-left:1ex"></blockquote><div><br></div></span><div>No, yo=
u just specify that &quot;return;&quot; is shorthand for &quot;return void(=
);&quot;. No one is suggesting that we break code like this. I don&#39;t th=
ink anyone in this thread was under that assumption. This isn&#39;t really =
much of a change, since you don&#39;t have to write &quot;return;&quot;, bu=
t rather, you can already, in valid C++, write &quot;return g();&quot;, whe=
re &quot;g&quot; is another function that returns void. It&#39;s more just =
syntactic sugar. Of note, if you really wanted to, you could even generaliz=
e that notion to mean that &quot;return;&quot; is just syntactic sugar for =
&quot;return T();&quot; where T is the return value of the function (I&#39;=
m not suggesting that we do this in the language, I&#39;m just using it as =
an example of its interpretation as syntactic sugar).=C2=A0</div></div></di=
v></div></blockquote><div><br></div><div>I just looked back and noticed you=
 mean the void foo(); and void(void) {} difference. I thought you meant the=
 return statement. I went over this later on in this reply anyway, but as m=
entioned several times in previous replies in this very thread, we are not =
proposing breaking the code that you&#39;ve shown. No meaning would change =
here because the implications would be too great. Instead, if you are in a =
place where void is not a dependent type, it has the current meaning. If de=
pendent, which is where we actually care about this and where void would no=
t produce a valid function declaration in C++, it means unary void. If you =
want to represent a unary void function in a non-dependent context you&#39;=
d just use some other syntax, which is unfortunate, but fine, and doesn&#39=
;t hurt generic code. There have been multiple suggestions for what that sy=
ntax would be.</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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a113cd18c87ce8a051c950f40--

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Wed, 05 Aug 2015 15:50:07 -0400
Raw View
On 2015-08-05 14:31, Matt Calabrese wrote:
> On Wed, Aug 5, 2015 at 6:54 AM, Matthew Woehlke wrote:
>> On 2015-08-04 19:15, Matt Calabrese wrote:
>>> On Tue, Aug 4, 2015 at 3:45 PM, Paul Fultz II wrote:
>>>> Also, having a type represent zero values is really necessary for
>>>> completeness, especially if we add variant to the language since `void`
>>>> is the identity element for variant.
>>>
>>> I have no doubt that you are trying to make a legitimate point here, but
>>> please ground this with an example, and explain precisely why you feel it
>>> makes sense to reuse "void" as such a type.
>>
>> ...because that's how it is *already* used?
>
> No, it's really not.

Really. 'void' means a function returns 0 values.

If you think of function returns as a tuple, this makes sense. Currently
we only support returning tuples of length 0 or length 1. A function
returning a 1-element tuple is expressed by naming the (non-void) type
of the single element in the tuple. A function returning a 0-element
tuple is expressed by 'void'.

Moreover, this is how the ABI (at least x86) works: a 1-tuple return is
stored (typically) in the EAX register. A 0-tuple return does not store
anything (contents of EAX are unspecified).

Similarly, '(void)' is synonymous with '()', i.e. an empty argument list.

*RIGHT NOW*, 'void' is used to indicate the absence of a value - i.e.
"zero values" - as a return type, and as an argument type. In general,
we need such a type, and 'void' is already serving in that manner.

> Similarly, in C++, it is already legal to return a void expression in
> the return statement of a function that returns void.

....which is good. Basically, a void value is just ignored, but right
now, only in limited contexts. The original suggestion looked at
expanding those contexts, and that is exactly what I suggested elsewhere
in the thread (as discussed below).

> Here we appear to be treating it as a value and copying it around,

Except you aren't.

I assure you, the following are equivalent:

  void bar1()
  {
    foo();
    return;
  }

  void bar2()
  {
    return foo();
  }

They *have to be*. Why? Because it would be surprising if foo() was not
called from bar2() (it is called), but foo() did not return a value, nor
does bar2() return a value. No copying can occur because there is
nothing to copy! If you inspect the generated assembly, it is identical.

> On Wed, Aug 5, 2015 at 6:54 AM, Matthew Woehlke wrote:
>>     void foo();
>>
>>     int main()
>>     {
>>         foo();
>>         return 0;
>>     }
>>
>>     void foo(void)
>>     {
>>         return;
>>     }
>>
>> (Note in particular that making void a regular type - i.e. 'struct
>> void{}' - WILL BREAK THIS! NOT ACCEPTABLE!)
>
> No, you just specify that "return;" is shorthand for "return void();".

Pedantic: So either you are still treating 'void' specially, or (as you
later suggested) you are making 'return;' shorthand for 'return {};' in
ALL cases.

The good news at least is that the latter is currently ill-formed, so
that should be okay in terms of not breaking existing code. I'm not sure
I'd actually care for such a change, however, but if you don't make it,
it's another case of still treating 'void' specially.

> No one is suggesting that we break code like this.

Pedantic: Making 'foo()' and 'foo(void)' different *was* suggested, at
least as I understood the discussion. I don't know that anyone is
seriously considering it, however, but...


This also made me realize another case that must not break:

  void foo() {}

(Although this is accepted currently even for non-void return type...
which, IMO, it shouldn't be...)

I could make muttering noises about how that must actually initialize
the return value, as if a 'return {};' had in fact been present, but
again, the reality of existing ABI's is that /there is no return value/
in the above.

This probably doesn't matter to real world implementations (there is no
return value to be initialized - /because 'void' is a zero-value/ - so
falling off the end of the function without initializing the return is
irrelevant), but - as in the relocatability discussion - the language
semantics might be another matter.

>> Rather (without getting into some of the more esoteric template
>> questions), it seems like the following should be made legal:
>>
>>     // allow void declaration; initialization is irrelevant
>>     void x;
>>
>>     // allow void assignment; exactly equivalent to:
>>     //     (void)foo(); void y;
>>     void y = foo();
>>
>>     // allow deduction from void
>>     auto z = x;
>>
>>     // allow passing void declaration as argument to function
>>     // taking zero arguments
>>     foo(x);
>>
>>     // allow comparing void declarations (see also relational operators
>>     // for Python's 'None')
>>     assert(x == y);
>>     assert(!(x != y));
>>
>>     // (optional) "allow" taking the address of a void declaration
>>     auto p = &x;
>>     assert(p == nullptr); // ...but 'x' has no storage
>
> This is just silly. What are you gaining by arbitrarily limiting to these
> operations like this and defining them in this manner?

There is no intention to limit anything. I think the above are things
that should be allowed (regardless of the implementation details that
make them allowed). I explicitly implied ("without getting into some of
the more esoteric template questions") that this is NOT an exhaustive list.

> Please refer to the many actual examples that I've accumulated
> throughout this thread (including why you shouldn't have argument
> collapsing) and the 0 examples that you have provided regarding the
> benefits of your representation for void in C++.

In fact, I reiterated one of your own examples and showed how it would
work with the above suggestions.

(Also, we need argument collapsing, at least for the '(void)' case. And
you agreed, so I won't belabor that point, but see next comment.)

>> In particular, I'm concerned that there doesn't seem to be enough
>> discussion how to preserve calling a function with argument list
>> "(void)" with no arguments, or calling a function taking no
>> arguments with a single argument of type 'void'.
>
> ??? What is "enough." This was already talked about pretty extensively. It
> is not proposed that void foo(void) {} changes meaning, because that would
> be a huge breaking change.

Then 'void' is not "simply a regular type". It means something special
in - at least - an argument list. (See also the reply I will write to
your other e-mail.)

--
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: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Wed, 05 Aug 2015 16:01:34 -0400
Raw View
On 2015-08-05 15:03, Matt Calabrese wrote:
> [...] if you are in a place where void is not a dependent type, it
> has the current meaning. If dependent, which is where we actually
> care about this and where void would not produce a valid function
> declaration in C++, it means unary void.

I thought about that. It might work for some of the template corner
cases. What isn't clear, however, is how it works in this case:

  void foo();
  void bar();

  auto x = foo();
  bar(x);

As I understand it, this is definitely one of the cases we want to
support. With the method I mentioned, where 'x' is named but has no
storage, 'bar(x)' naturally decays to 'bar()' and there is no issue. For
a strict interpretation of your above idea, decltype(x) == void_t (or
whatever, but anyway != void), and again you need special rules for
void_t in order to be able to "pass" it (or more pedantically, *not*
pass it) to a zero-argument function.

Similarly, we want this case to work:

  template <typename T> class future { set_value(T const&); };
  future<void> f;
  f.set_value();

....and again this requires special rules, something along the lines of
'a function taking a single void_t (with whatever CV qualifiers) may be
invoked with zero arguments'.

--
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: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Wed, 5 Aug 2015 15:30:30 -0700
Raw View
--001a113cd18c4464fe051c97f37c
Content-Type: text/plain; charset=UTF-8

On Wed, Aug 5, 2015 at 12:50 PM, Matthew Woehlke <mwoehlke.floss@gmail.com>
wrote:
>
> Pedantic: So either you are still treating 'void' specially, or (as you
> later suggested) you are making 'return;' shorthand for 'return {};' in
> ALL cases.
>

Neither of these should really matter. Most types are "special" in *that*
sense of the word (character literals are a pretty unique way to create
chars, for example, and any type can have its own member functions that no
other type has). The "special" that poses a problem in generic code is when
a given type does not meet the minimal requirements that the code needs in
order to operate, and yet there is no practical reason for why the type in
question cannot model those requirements. I.E. void is not regular.
Similarly, if the type means something different with respect to argument
passing (such as if we had argument collapsing) then it also poses a
problem. Why it is beneficial for void to at least be regular has been
shown with many examples, covering instantiability, copying, comparing,
passing as individual arguments, You are working toward a particular
abstraction, but you are failing to get a across to me why you feel that
that particular abstraction is more beneficial to model than void being a
regular type.

> No one is suggesting that we break code like this.
>
> Pedantic: Making 'foo()' and 'foo(void)' different *was* suggested, at
> least as I understood the discussion. I don't know that anyone is
> seriously considering it, however, but...
>

True.

This also made me realize another case that must not break:
>
>   void foo() {}
>
> (Although this is accepted currently even for non-void return type...
> which, IMO, it shouldn't be...)
>

Agreed. To be clear, our goal isn't to go out and not worry about breaking
things (okay, I guess Sean disagrees on the part, :p). This is why I don't
even support the change in meaning of "void foo(void)" in a context where
void is not dependent.


> There is no intention to limit anything. I think the above are things
> that should be allowed (regardless of the implementation details that
> make them allowed). I explicitly implied ("without getting into some of
> the more esoteric template questions") that this is NOT an exhaustive list.
>

If it's not an exhaustive list, can you enumerate exactly the differences
compared to a void that is simply a regular type? This way we can make sure
we are only focusing on the differences.


> > Please refer to the many actual examples that I've accumulated
> > throughout this thread (including why you shouldn't have argument
> > collapsing) and the 0 examples that you have provided regarding the
> > benefits of your representation for void in C++.
>
> In fact, I reiterated one of your own examples and showed how it would
> work with the above suggestions.
>

You pointed out that it would work if a log_success() overload exists. We
know that, but that separate nullary overload simply does not have to exist
at all if void were simply a regular type. The default template works fine
and it can forward allong data, etc. As well, if you expand collapsing to
apply to voids that appear in arbitrary parameter lists, as has been
suggested, you can very quickly run into odd failures and ambiguities if
one of your dependent types is void. Consider the following:

//////////
enum class log_option { simple, verbose };

template<class T>
void log(T what_to_log, log_option option = log_option::simple);

template<class Fun>
void log_result(Fun fun) {
  log(fun(), log_option::verbose);
}

int main() {
  // logs an int using the verbose option
  log_result([]{ return 0; });

  // If internally the first argument "collapses" because the function
returns void,
  // then we are no longer logging "void" with the "verbose" option, but
instead,
  // we are logging an instance of "log_option" with the "simple" option.
  log_result([]{});
}
//////////

On the other hand, when you simply treat void as a regular type without
"collapsing" or any magic, this just works and there is no reason why it
shouldn't. Nothing at all is subtle and you don't have to think of void as
something special with special rules for arguments. There is nothing tricky
at play and you don't need to special case for void.

(Also, we need argument collapsing, at least for the '(void)' case. And
> you agreed, so I won't belabor that point, but see next comment.)
>

I do not believe I ever agreed with such a statement, but if I did it was a
mistake. The expression "foo(`some-expression-yielding-void`)" ideally
should not be a valid way to invoke a true nullary function called "foo,"
and it's also not valid in current C++.

>
> > ??? What is "enough." This was already talked about pretty extensively.
> It
> > is not proposed that void foo(void) {} changes meaning, because that
> would
> > be a huge breaking change.
>
> Then 'void' is not "simply a regular type". It means something special
> in - at least - an argument list. (See also the reply I will write to
> your other e-mail.)
>

That doesn't make void not regular. To be clear, when I say regular, I mean
a model of Regular ( http://www.stepanovpapers.com/DeSt98.pdf ). It is
unfortunate that we cannot realistically change the meaning of "void
foo(void) {}" because it would cause too much breakage, but that is a
separate issue. If I thought that had any chance at all of getting through
standardization and also not break too much code, then I would be in favor
of it. Realistically, we need to be practical.

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On W=
ed, Aug 5, 2015 at 12:50 PM, Matthew Woehlke <span dir=3D"ltr">&lt;<a href=
=3D"mailto:mwoehlke.floss@gmail.com" target=3D"_blank">mwoehlke.floss@gmail=
..com</a>&gt;</span> wrote:<blockquote class=3D"gmail_quote" style=3D"margin=
:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Pedantic: So either you are still treating &#39;void&#39; specially, or (as=
 you<br>
later suggested) you are making &#39;return;&#39; shorthand for &#39;return=
 {};&#39; in<br>
ALL cases.<br></blockquote><div><br></div><div>Neither of these should real=
ly matter. Most types are &quot;special&quot; in <i>that</i> sense of the w=
ord (character literals are a pretty unique way to create chars, for exampl=
e, and any type can have its own member functions that no other type has). =
The &quot;special&quot; that poses a problem in generic code is when a give=
n type does not meet the minimal requirements that the code needs in order =
to operate, and yet there is no practical reason for why the type in questi=
on cannot model those requirements. I.E. void is not regular. Similarly, if=
 the type means something different with respect to argument passing (such =
as if we had argument collapsing) then it also poses a problem. Why it is b=
eneficial for void to at least be regular has been shown with many examples=
, covering instantiability, copying, comparing, passing as individual argum=
ents,=C2=A0You are working toward a particular abstraction, but you are fai=
ling to get a across to me why you feel that that particular abstraction is=
 more beneficial to model than void being a regular type.</div><div><br></d=
iv><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left=
:1px #ccc solid;padding-left:1ex">
&gt; No one is suggesting that we break code like this.<br>
<br>
Pedantic: Making &#39;foo()&#39; and &#39;foo(void)&#39; different *was* su=
ggested, at<br>
least as I understood the discussion. I don&#39;t know that anyone is<br>
seriously considering it, however, but...<br></blockquote><div><br></div><d=
iv>True.=C2=A0</div><div><br></div><blockquote class=3D"gmail_quote" style=
=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
This also made me realize another case that must not break:<br>
<br>
=C2=A0 void foo() {}<br>
<br>
(Although this is accepted currently even for non-void return type...<br>
which, IMO, it shouldn&#39;t be...)<br></blockquote><div><br></div><div>Agr=
eed. To be clear, our goal isn&#39;t to go out and not worry about breaking=
 things (okay, I guess Sean disagrees on the part, :p). This is why I don&#=
39;t even support the change in meaning of &quot;void foo(void)&quot; in a =
context where void is not dependent.</div><div>=C2=A0</div><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;pad=
ding-left:1ex">There is no intention to limit anything. I think the above a=
re things<br>
that should be allowed (regardless of the implementation details that<br>
make them allowed). I explicitly implied (&quot;without getting into some o=
f<br>
the more esoteric template questions&quot;) that this is NOT an exhaustive =
list.<br></blockquote><div><br></div><div>If it&#39;s not an exhaustive lis=
t, can you enumerate exactly the differences compared to a void that is sim=
ply a regular type? This way we can make sure we are only focusing on the d=
ifferences.</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=
=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
&gt; Please refer to the many actual examples that I&#39;ve accumulated<br>
&gt; throughout this thread (including why you shouldn&#39;t have argument<=
br>
&gt; collapsing) and the 0 examples that you have provided regarding the<br=
>
&gt; benefits of your representation for void in C++.<br>
<br>
In fact, I reiterated one of your own examples and showed how it would<br>
work with the above suggestions.<br></blockquote><div><br></div><div>You po=
inted out that it would work if a log_success() overload exists. We know th=
at, but that separate nullary overload simply does not have to exist at all=
 if void were simply a regular type. The default template works fine and it=
 can forward allong data, etc. As well, if you expand collapsing to apply t=
o voids that appear in arbitrary parameter lists, as has been suggested, yo=
u can very quickly run into odd failures and ambiguities if one of your dep=
endent types is void. Consider the following:</div><div><br></div><div>////=
//////</div><div>enum class log_option { simple, verbose };</div><div><br><=
/div><div>template&lt;class T&gt;</div><div>void log(T what_to_log, log_opt=
ion option =3D log_option::simple);</div><div><br></div><div>template&lt;cl=
ass Fun&gt;</div><div>void log_result(Fun fun) {</div><div>=C2=A0 log(fun()=
, log_option::verbose);</div><div>}</div><div><br></div><div>int main() {</=
div><div>=C2=A0 // logs an int using the verbose option</div>=C2=A0 log_res=
ult([]{ return 0; });</div><div class=3D"gmail_quote"><br></div><div class=
=3D"gmail_quote">=C2=A0 // If internally the first argument &quot;collapses=
&quot; because the function returns void,</div><div class=3D"gmail_quote">=
=C2=A0 // then we are no longer logging &quot;void&quot; with the &quot;ver=
bose&quot; option, but instead,</div><div class=3D"gmail_quote">=C2=A0 // w=
e are logging an instance of &quot;log_option&quot; with the &quot;simple&q=
uot; option.<br><div>=C2=A0 log_result([]{});</div><div>}</div><div>///////=
///</div><div><br></div><div>On the other hand, when you simply treat void =
as a regular type without &quot;collapsing&quot; or any magic, this just wo=
rks and there is no reason why it shouldn&#39;t. Nothing at all is subtle a=
nd you don&#39;t have to think of void as something special with special ru=
les for arguments. There is nothing tricky at play and you don&#39;t need t=
o special case for void.</div><div><br></div><blockquote class=3D"gmail_quo=
te" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"=
>(Also, we need argument collapsing, at least for the &#39;(void)&#39; case=
.. And<br>
you agreed, so I won&#39;t belabor that point, but see next comment.)<br></=
blockquote><div><br></div><div>I do not believe I ever agreed with such a s=
tatement, but if I did it was a mistake. The expression &quot;foo(`some-exp=
ression-yielding-void`)&quot; ideally should not be a valid way to invoke a=
 true nullary function called &quot;foo,&quot; and it&#39;s also not valid =
in current C++.</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 =
0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
&gt; ??? What is &quot;enough.&quot; This was already talked about pretty e=
xtensively. It<br>
&gt; is not proposed that void foo(void) {} changes meaning, because that w=
ould<br>
&gt; be a huge breaking change.<br>
<br>
Then &#39;void&#39; is not &quot;simply a regular type&quot;. It means some=
thing special<br>
in - at least - an argument list. (See also the reply I will write to<br>
your other e-mail.)<br></blockquote><div><br></div><div>That doesn&#39;t ma=
ke void not regular. To be clear, when I say regular, I mean a model of Reg=
ular (=C2=A0<a href=3D"http://www.stepanovpapers.com/DeSt98.pdf">http://www=
..stepanovpapers.com/DeSt98.pdf</a> ). It is unfortunate that we cannot real=
istically change the meaning of &quot;void foo(void) {}&quot; because it wo=
uld cause too much breakage, but that is a separate issue. If I thought tha=
t had any chance at all of getting through standardization and also not bre=
ak too much code, then I would be in favor of it. Realistically, we need to=
 be practical.</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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a113cd18c4464fe051c97f37c--

.


Author: Paul Fultz II <pfultz28@gmail.com>
Date: Wed, 5 Aug 2015 15:58:22 -0700 (PDT)
Raw View
------=_Part_353_1081549125.1438815502500
Content-Type: multipart/alternative;
 boundary="----=_Part_354_987730522.1438815502500"

------=_Part_354_987730522.1438815502500
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



On Wednesday, August 5, 2015 at 4:58:31 AM UTC-5, Miro Knejp wrote:
>
>
> On 05 Aug 2015, at 09:42 , Roland Bock <rb...@eudoxos.de <javascript:>>=
=20
> wrote:
>
> Ok, so that page says:
>
> In C, C++, C#, and Java, void expresses the empty type. The unit type in =
C=20
> would be struct {}, but an empty struct is forbidden by the C language=20
> specification .
>
>
> But if we go all Wikipedia, then also add this page here:
>
> https://en.wikipedia.org/wiki/Bottom_type (aka empty type)
> In type theory, a theory within mathematical logic, the bottom type is th=
e=20
> type that has no values. It is also called the zero or empty type. The=20
> bottom type is sometimes confused with the *so-called "void type", which=
=20
> is actually a unit type*, albeit one with no defined operations.
>
> So Wikipedia says:
>
>   * void is the bottom type (no value)
>   * void is a unit type (exactly one value)
>
> Wikipedia contradicts itself, thus it cannot really be used to decide. ;-=
)
>
> I guess that is where most of the confusion in this thread arises from.=
=20
> Some want to interpret void as the value-less bottom type, others want to=
=20
> interpret void as a unit type (exactly one value).
>
> Thus, when making statement about how void should behave, you should stat=
e=20
> whether you are in the "bottom type" or in the "unit type" fraction.
>
>
> As of now, I am a member of the "unit type" fraction: void does have a=20
> value which - for instance - says that a function has finished regularly,=
=20
> in contrast to not returning at all, throwing an exception, or aborting t=
he=20
> program.
>
>
> Yay for contradictions. I=E2=80=99d say that void as it stands in C++ now=
 is=20
> somewhere between the bottom and unit type. It is really neither of them:
>
> - Functions marked with void do return to the caller but shouldn=E2=80=99=
t if void=20
> was the bottom type
> - Functions marked with void or taking void do not take or return values,=
=20
> but they would take or return the singular unit value if void were a unit=
=20
> type
>
> In a perfect world C++ would have a builtin unit type and a builtin botto=
m=20
> type (so everyone would use those by default instead of rolling their own=
),=20
> right now it really has neither. Considering the status quo void would be=
=20
> much more useful in practice as a unit type. The vast majority of functio=
ns=20
> do terminate so the need for a real bottom type is minuscule.
>

Reading about the bottom type, it does seem like `void` is more like the=20
unit type(although not completely). The very fact that the function returns=
=20
means a value exists(although it is not an addressable value in the=20
language), whereas having a true bottom type(such as `noreturn`) would mean=
=20
no value would ever exists(since the function essentially halts). However,=
=20
C/C++ is different from pure functional languages in that functions don't=
=20
just transform values, they also can be purely side effects(like the=20
functions that returns `void`). This is why we have a special type of=20
`void` to represent that. Changing `void` to be completely a regular unit=
=20
type would allow composing functions of pure side effects, I don't know if=
=20
that always makes sense. It seems it would weaken the type safety. Perhaps=
=20
for some generic code it might be simpler, but for others it could compile=
=20
incorrect code or misdiagnose the true error in code.=20

--=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_354_987730522.1438815502500
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<br><br>On Wednesday, August 5, 2015 at 4:58:31 AM UTC-5, Miro Knejp wrote:=
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;"><div style=3D"word-wrap:break-=
word"><br><div><blockquote type=3D"cite"><div>On 05 Aug 2015, at 09:42 , Ro=
land Bock &lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mail=
to=3D"lGZ48AcmEAAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javasc=
ript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;retur=
n true;">rb...@eudoxos.de</a>&gt; wrote:</div><br><div>
 =20
   =20
 =20
  <div bgcolor=3D"#FFFFFF" text=3D"#000000">
    <div>Ok, so that page says:</div>
    <br>
    In C, C++, C#, and Java, void expresses the empty type. The unit
    type in C would be struct {}, but an empty struct is forbidden by
    the C language specification
   =20
    .<br>
   =20
    <br>
    <br>
    But if we go all Wikipedia, then also add this page here:<br>
    <br>
    <a href=3D"https://en.wikipedia.org/wiki/Bottom_type" target=3D"_blank"=
 rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;https://www.google.com/ur=
l?q\75https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FBottom_type\46sa\75D\46sntz\0=
751\46usg\75AFQjCNHN2zGVQ4Z5M9TLlFJI1VIqvZJwtg&#39;;return true;" onclick=
=3D"this.href=3D&#39;https://www.google.com/url?q\75https%3A%2F%2Fen.wikipe=
dia.org%2Fwiki%2FBottom_type\46sa\75D\46sntz\0751\46usg\75AFQjCNHN2zGVQ4Z5M=
9TLlFJI1VIqvZJwtg&#39;;return true;">https://en.wikipedia.org/wiki/<wbr>Bot=
tom_type</a> (aka empty type)<br>
    In type theory, a theory within mathematical logic, the bottom type
    is the type that has no values. It is also called the zero or empty
    type. The bottom type is sometimes confused with the <i>so-called
      &quot;void type&quot;, which is actually a unit type</i>, albeit one =
with no
    defined operations.<br>
    <br>
    So Wikipedia says:<br>
    <br>
    =C2=A0 * void is the bottom type (no value)<br>
    =C2=A0 * void is a unit type (exactly one value)<br>
    <br>
    Wikipedia contradicts itself, thus it cannot really be used to
    decide. ;-)<br>
    <br>
    I guess that is where most of the confusion in this thread arises
    from. Some want to interpret void as the value-less bottom type,
    others want to interpret void as a unit type (exactly one value).<br>
    <br>
    Thus, when making statement about how void should behave, you should
    state whether you are in the &quot;bottom type&quot; or in the &quot;un=
it type&quot;
    fraction.<br>
    <br>
    <br>
    As of now, I am a member of the &quot;unit type&quot; fraction: void do=
es have
    a value which - for instance - says that a function has finished
    regularly, in contrast to not returning at all, throwing an
    exception, or aborting the program.<br></div></div></blockquote></div><=
br><div>Yay for contradictions. I=E2=80=99d say that void as it stands in C=
++ now is somewhere between the bottom and unit type. It is really neither =
of them:</div><div><br></div><div>- Functions marked with void do return to=
 the caller but shouldn=E2=80=99t if void was the bottom type</div><div>- F=
unctions marked with void or taking void do not take or return values, but =
they would take or return the singular unit value if void were a unit type<=
/div><div><br></div><div>In a perfect world C++ would have a builtin unit t=
ype and a builtin bottom type (so everyone would use those by default inste=
ad of rolling their own), right now it really has neither. Considering the =
status quo void would be much more useful in practice as a unit type. The v=
ast majority of functions do terminate so the need for a real bottom type i=
s minuscule.</div></div></blockquote><div><br>Reading about the bottom type=
, it does seem like `void` is more like the unit type(although not complete=
ly). The very fact that the function returns means a value exists(although =
it is not an addressable value in the language), whereas having a true bott=
om type(such as `noreturn`) would mean no value would ever exists(since the=
 function essentially halts). However, C/C++ is different from pure functio=
nal languages in that functions don&#39;t just transform values, they also =
can be purely side effects(like the functions that returns `void`). This is=
 why we have a special type of `void` to represent that. Changing `void` to=
 be completely a regular unit type would allow composing functions of pure =
side effects, I don&#39;t know if that always makes sense. It seems it woul=
d weaken the type safety. Perhaps for some generic code it might be simpler=
, but for others it could compile incorrect code or misdiagnose the true er=
ror in code. <br><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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_354_987730522.1438815502500--
------=_Part_353_1081549125.1438815502500--

.


Author: Roland Bock <rbock@eudoxos.de>
Date: Thu, 06 Aug 2015 13:47:09 +0200
Raw View
This is a multi-part message in MIME format.
--------------000406070009070008010207
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On 2015-08-06 00:58, Paul Fultz II wrote:
>
>
> On Wednesday, August 5, 2015 at 4:58:31 AM UTC-5, Miro Knejp wrote:
>
>
>>     On 05 Aug 2015, at 09:42 , Roland Bock <rb...@eudoxos.de
>>     <javascript:>> wrote:
>>
>>     Ok, so that page says:
>>
>>     In C, C++, C#, and Java, void expresses the empty type. The unit
>>     type in C would be struct {}, but an empty struct is forbidden by
>>     the C language specification .
>>
>>
>>     But if we go all Wikipedia, then also add this page here:
>>
>>     https://en.wikipedia.org/wiki/Bottom_type
>>     <https://en.wikipedia.org/wiki/Bottom_type> (aka empty type)
>>     In type theory, a theory within mathematical logic, the bottom
>>     type is the type that has no values. It is also called the zero
>>     or empty type. The bottom type is sometimes confused with the
>>     /so-called "void type", which is actually a unit type/, albeit
>>     one with no defined operations.
>>
>>     So Wikipedia says:
>>
>>       * void is the bottom type (no value)
>>       * void is a unit type (exactly one value)
>>
>>     Wikipedia contradicts itself, thus it cannot really be used to
>>     decide. ;-)
>>
>>     I guess that is where most of the confusion in this thread arises
>>     from. Some want to interpret void as the value-less bottom type,
>>     others want to interpret void as a unit type (exactly one value).
>>
>>     Thus, when making statement about how void should behave, you
>>     should state whether you are in the "bottom type" or in the "unit
>>     type" fraction.
>>
>>
>>     As of now, I am a member of the "unit type" fraction: void does
>>     have a value which - for instance - says that a function has
>>     finished regularly, in contrast to not returning at all, throwing
>>     an exception, or aborting the program.
>
>     Yay for contradictions. I=E2=80=99d say that void as it stands in C++=
 now
>     is somewhere between the bottom and unit type. It is really
>     neither of them:
>
>     - Functions marked with void do return to the caller but shouldn=E2=
=80=99t
>     if void was the bottom type
>     - Functions marked with void or taking void do not take or return
>     values, but they would take or return the singular unit value if
>     void were a unit type
>
>     In a perfect world C++ would have a builtin unit type and a
>     builtin bottom type (so everyone would use those by default
>     instead of rolling their own), right now it really has neither.
>     Considering the status quo void would be much more useful in
>     practice as a unit type. The vast majority of functions do
>     terminate so the need for a real bottom type is minuscule.
>
>
> Reading about the bottom type, it does seem like `void` is more like
> the unit type(although not completely). The very fact that the
> function returns means a value exists(although it is not an
> addressable value in the language), whereas having a true bottom
> type(such as `noreturn`) would mean no value would ever exists(since
> the function essentially halts). However, C/C++ is different from pure
> functional languages in that functions don't just transform values,
> they also can be purely side effects(like the functions that returns
> `void`). This is why we have a special type of `void` to represent
> that. Changing `void` to be completely a regular unit type would allow
> composing functions of pure side effects, I don't know if that always
> makes sense. It seems it would weaken the type safety. Perhaps for
> some generic code it might be simpler, but for others it could compile
> incorrect code or misdiagnose the true error in code.

Turning void into a regular unit type certainly has effects. But how
would it lead to misdiagnosis? Do you have an example in mind?

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

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

<html>
  <head>
    <meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Type=
">
  </head>
  <body bgcolor=3D"#FFFFFF" text=3D"#000000">
    <div class=3D"moz-cite-prefix">On 2015-08-06 00:58, Paul Fultz II
      wrote:<br>
    </div>
    <blockquote
      cite=3D"mid:cb7e270b-2341-4e5d-8f38-aba3a4ff20e1@isocpp.org"
      type=3D"cite"><br>
      <br>
      On Wednesday, August 5, 2015 at 4:58:31 AM UTC-5, Miro Knejp
      wrote:
      <blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:
        0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
        <div style=3D"word-wrap:break-word"><br>
          <div>
            <blockquote type=3D"cite">
              <div>On 05 Aug 2015, at 09:42 , Roland Bock &lt;<a
                  moz-do-not-send=3D"true" href=3D"javascript:"
                  target=3D"_blank" gdf-obfuscated-mailto=3D"lGZ48AcmEAAJ"
                  rel=3D"nofollow"
                  onmousedown=3D"this.href=3D'javascript:';return true;"
                  onclick=3D"this.href=3D'javascript:';return true;">rb...@=
eudoxos.de</a>&gt;
                wrote:</div>
              <br>
              <div>
                <div bgcolor=3D"#FFFFFF" text=3D"#000000">
                  <div>Ok, so that page says:</div>
                  <br>
                  In C, C++, C#, and Java, void expresses the empty
                  type. The unit type in C would be struct {}, but an
                  empty struct is forbidden by the C language
                  specification .<br>
                  <br>
                  <br>
                  But if we go all Wikipedia, then also add this page
                  here:<br>
                  <br>
                  <a moz-do-not-send=3D"true"
                    href=3D"https://en.wikipedia.org/wiki/Bottom_type"
                    target=3D"_blank" rel=3D"nofollow"
                    onmousedown=3D"this.href=3D'https://www.google.com/url?=
q\75https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FBottom_type\46sa\75D\46sntz\075=
1\46usg\75AFQjCNHN2zGVQ4Z5M9TLlFJI1VIqvZJwtg';return
                    true;"
                    onclick=3D"this.href=3D'https://www.google.com/url?q\75=
https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FBottom_type\46sa\75D\46sntz\0751\46=
usg\75AFQjCNHN2zGVQ4Z5M9TLlFJI1VIqvZJwtg';return
                    true;">https://en.wikipedia.org/wiki/<wbr>Bottom_type</=
a>
                  (aka empty type)<br>
                  In type theory, a theory within mathematical logic,
                  the bottom type is the type that has no values. It is
                  also called the zero or empty type. The bottom type is
                  sometimes confused with the <i>so-called "void type",
                    which is actually a unit type</i>, albeit one with
                  no defined operations.<br>
                  <br>
                  So Wikipedia says:<br>
                  <br>
                  =C2=A0 * void is the bottom type (no value)<br>
                  =C2=A0 * void is a unit type (exactly one value)<br>
                  <br>
                  Wikipedia contradicts itself, thus it cannot really be
                  used to decide. ;-)<br>
                  <br>
                  I guess that is where most of the confusion in this
                  thread arises from. Some want to interpret void as the
                  value-less bottom type, others want to interpret void
                  as a unit type (exactly one value).<br>
                  <br>
                  Thus, when making statement about how void should
                  behave, you should state whether you are in the
                  "bottom type" or in the "unit type" fraction.<br>
                  <br>
                  <br>
                  As of now, I am a member of the "unit type" fraction:
                  void does have a value which - for instance - says
                  that a function has finished regularly, in contrast to
                  not returning at all, throwing an exception, or
                  aborting the program.<br>
                </div>
              </div>
            </blockquote>
          </div>
          <br>
          <div>Yay for contradictions. I=E2=80=99d say that void as it stan=
ds in
            C++ now is somewhere between the bottom and unit type. It is
            really neither of them:</div>
          <div><br>
          </div>
          <div>- Functions marked with void do return to the caller but
            shouldn=E2=80=99t if void was the bottom type</div>
          <div>- Functions marked with void or taking void do not take
            or return values, but they would take or return the singular
            unit value if void were a unit type</div>
          <div><br>
          </div>
          <div>In a perfect world C++ would have a builtin unit type and
            a builtin bottom type (so everyone would use those by
            default instead of rolling their own), right now it really
            has neither. Considering the status quo void would be much
            more useful in practice as a unit type. The vast majority of
            functions do terminate so the need for a real bottom type is
            minuscule.</div>
        </div>
      </blockquote>
      <div><br>
        Reading about the bottom type, it does seem like `void` is more
        like the unit type(although not completely). The very fact that
        the function returns means a value exists(although it is not an
        addressable value in the language), whereas having a true bottom
        type(such as `noreturn`) would mean no value would ever
        exists(since the function essentially halts). However, C/C++ is
        different from pure functional languages in that functions don't
        just transform values, they also can be purely side effects(like
        the functions that returns `void`). This is why we have a
        special type of `void` to represent that. Changing `void` to be
        completely a regular unit type would allow composing functions
        of pure side effects, I don't know if that always makes sense.
        It seems it would weaken the type safety. Perhaps for some
        generic code it might be simpler, but for others it could
        compile incorrect code or misdiagnose the true error in code. <br>
      </div>
    </blockquote>
    <br>
    Turning void into a regular unit type certainly has effects. But how
    would it lead to misdiagnosis? Do you have an example in mind?<br>
    <br>
  </body>
</html>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--------------000406070009070008010207--

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Thu, 06 Aug 2015 10:52:12 -0400
Raw View
On 2015-08-05 18:30, Matt Calabrese wrote:
> On Wed, Aug 5, 2015 at 12:50 PM, Matthew Woehlke wrote:
>> There is no intention to limit anything. I think the above are things
>> that should be allowed (regardless of the implementation details that
>> make them allowed). I explicitly implied ("without getting into some of
>> the more esoteric template questions") that this is NOT an exhaustive list.
>
> If it's not an exhaustive list, can you enumerate exactly the differences
> compared to a void that is simply a regular type? This way we can make sure
> we are only focusing on the differences.

Honestly, I'm not entirely convinced that I'm opposed to the idea,
although neither am I entirely convinced of the necessity. My main
concerns are about not changing the meaning of existing code and
behaving sensibly w.r.t. empty returns and argument lists. I won't
rehash all of those, but a few cases in particular:

  template <typename T> foo(T const&);
  foo<void>(); // should work

  void bar();
  auto x = bar(); // should work
  void y = bar(); // should also work?

....and I'm not convinced that a void variable should actually have storage.

What to do with something like this:

  template <typename Args...> foo(Args const&... args);
  foo<int, void, int>( /* what can legally go here? */ );

....is a much thornier question I think that honestly I am trying to
avoid. I'm less convinced of the need to solve *this* than more obvious
cases, such as assigning a void, returning a void variable, passing a
single void to a function taking no arguments, passing no arguments to a
template function taking a template, [CV-qualified] void, etc.

That's why I enumerated a number of such cases in my previous e-mail. I
think if we can solve these without breaking existing code, we are
probably on the right track, regardless of the actual wording that
provides those solutions.

Hope that helps.

> You pointed out that it would work if a log_success() overload exists. We
> know that, but that separate nullary overload simply does not have to exist
> at all if void were simply a regular type.

....or if a log_success(void) exists (where that 'void' may be
dependent). Which, per above, can also be called as a zero-argument
function. (I'm not assuming that log_success(...) is templated.) Really,
what I meant was that there exists an overload that can be called with a
single void argument. A zero-argument overload would fit that bill. One
taking a dependent-type void would also.

(Then there is the question of which one is preferred in overload
resolution. I guess if the call provides a void argument, then the
dependent-type version should be preferred. On the flip side, should a
zero-argument call ever call a <void> function? Do we provide something
like std::void_t to allow a non-template overload taking a void argument?)

And again, the answer to that first question is at least partly "yes".
I'm less convinced that a zero-argument call should cause instantiation
with <void>. However, if instantiation has already occurred, then
passing zero arguments SHOULD be able to call a function taking a
dependent void. IOW, these two examples need to work:

  template <typename T> foo(T const&);
  foo<void>();

  template <typename T> class Bar { void bar(T const&); };
  Bar{}.bar();

The latter you'll recall is specifically needed to avoid specializing
std::future.

Note also that we MUST either allow 'void bar(); foo(bar())' to call a
'foo()', or else provide something like std::void_t, or we have not
solved the generic programming case where a template calls a function
that has only explicit overloads but is not itself templated. Or
specifically excludes 'void' from template instantiation. (I could
readily imagine your logging example doing this, for example, e.g. to
print a slightly different message depending on whether or not the
called function returns a result, i.e. return type is 'void' or not.)

--
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: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Thu, 6 Aug 2015 12:14:22 -0700
Raw View
--001a113cd18cafcb21051ca9538b
Content-Type: text/plain; charset=UTF-8

On Thu, Aug 6, 2015 at 7:52 AM, Matthew Woehlke <mwoehlke.floss@gmail.com>
wrote:
>
> Honestly, I'm not entirely convinced that I'm opposed to the idea,
> although neither am I entirely convinced of the necessity. My main
> concerns are about not changing the meaning of existing code and
> behaving sensibly w.r.t. empty returns and argument lists. I won't
> rehash all of those, but a few cases in particular:
>
>   template <typename T> foo(T const&);
>   foo<void>(); // should work
>

I actually don't think it's strictly sound for that to work even though we
might want it. The only reason to allow it is to ease the transition of
APIs. Initially, I thought it would be very useful and was championing
that, but the more I formalize things, the more fragile and also less
useful it seems. There are more sound alternatives that API developers
could make when updating their code that eases the transition for users
(temporarily adding a default for the API transition, for instance, if only
for the void case). The main problem with supporting the case you've shown
is that, apart from it not being strictly logically sound, even though we
can make it "work," it can cause subtle breaks in existing code due to more
overloads being considered and more templates going through substitution
when no argument is seemingly passed (you'd now have to consider both
nullary and unary cases for a single empty argument, just preferring
nullary as a better match).

FWIW, last night I started sketching out a proposal for my current thoughts
on what a revised "void" type would be (sorry I hijacked this thread --
competing proposals are fine since this still looks controversial, I just
really feel pretty strongly about some of this stuff). I went through all
of the changes that we'd hypothetically need to make to Core in order to
have a very minimal "void as a regular type" proposal, and I did not touch
on handling the above situation, nor did I touch on "empty" argument
meaning "default-constructed-void" at all, so unless others convince me the
other way, it might just serve as a note in my proposal without actually
being formally proposed. Without such changes and without a decision yet on
how to represent a unary void function type when void is not dependent,
there are actually surprisingly minimal changes required for Core. I don't
have it in front of me, but there was only something like 5 or 6 changes to
definitions (void is now a complete object type that is also a scalar and
has the operators associated with a regular type, subtle change to the
conditional operator that likely needs another pass to make sure nothing
breaks, allowing void as a non-type template parameter type, and probably
one or two things I don't remember), and then there were about 30 removals
in various places where "void" was explicitly mentioned due to those
mentions now either being redundant or no longer true as a consequence of
void being a complete, object type that is a scalar.

Other things of note that came up were whether or not user-defined
conversion to void should be allowed. Logically there isn't anything wrong
with it and it could hypothetically come up in generic code, but it's also
a breaking change since people can currently cast expressions to void in
generic code such that they can safely use something like comma without
risking pulling in an overload. Similarly, if people can overload comma for
when exactly one of the operands is void, that has implications when
writing correct generic code, too -- as for why, it's for some similar
reasons as to why you'd want to use std::addressof in generic code. My
current thoughts are to (unfortunately) leave these special-cased for now
and address them separately.

Ultimately I think it's hard to figure out exactly what is okay to break
and what is "necessary" for the transition until we hack together an
implementation and actually fully examine all of the implications for the
standard library (such as possible removal of the void specialization from
promise).

On Thu, Aug 6, 2015 at 7:52 AM, Matthew Woehlke <mwoehlke.floss@gmail.com>
 wrote:

>   void bar();
>   auto x = bar(); // should work
>   void y = bar(); // should also work?
>

Sure, why not? What problem would this cause?

On Thu, Aug 6, 2015 at 7:52 AM, Matthew Woehlke <mwoehlke.floss@gmail.com>
 wrote:

> What to do with something like this:
>
>   template <typename Args...> foo(Args const&... args);
>   foo<int, void, int>( /* what can legally go here? */ );
>
> ...is a much thornier question.
>

I don't see an issue. void is just a regular type.You can call it as
"foo(1, void(), 3);" for example. Any expression yielding void can be used
as that second argument, just like with other types. If supporting the
"empty argument meaning default-constructed-void" possibility, you could
also just have empty-space between the commas. Again though, I'm not
actually suggesting that in what I've sketched out so far.

On Thu, Aug 6, 2015 at 7:52 AM, Matthew Woehlke <mwoehlke.floss@gmail.com>
 wrote:

> ...or if a log_success(void) exists (where that 'void' may be
> dependent). Which, per above, can also be called as a zero-argument
> function. (I'm not assuming that log_success(...) is templated.) Really,
> what I meant was that there exists an overload that can be called with a
> single void argument. A zero-argument overload would fit that bill. One
> taking a dependent-type void would also.
>

Ah, ok.

On Thu, Aug 6, 2015 at 7:52 AM, Matthew Woehlke <mwoehlke.floss@gmail.com>
 wrote:

> (Then there is the question of which one is preferred in overload
> resolution. I guess if the call provides a void argument, then the
> dependent-type version should be preferred. On the flip side, should a
> zero-argument call ever call a <void> function? Do we provide something
> like std::void_t to allow a non-template overload taking a void argument?)
>

These issues don't exit when void is an object type and there is no
collapsing or anything. If a function takes a void argument and it doesn't
have a default, then you simply must pass a void expression. If a function
takes no arguments, you simply cannot pass void. They are distinct and
incompatible cases. Right now we only have a way of representing the
nullary case, so the transition could have hiccups, but we'd end up with
something that is sound. The "empty possibly meaning default-construct
void" thing straddles the line and also attempts to address this, but I
find it less and less appealing. The rule would (effectively) have been
that if you pass in no argument such as invoking it as "foo()", then the
overloads that are considered are the combined set of both "foo(/*truly no
arg*/)" and "foo(void()))", preferring nullary versions as a better match
when there are multiple viable candidates. Rather than going down this
route, though, I think the conservative approach is to not muck with
overload resolution as it is scary and fragile (and this wouldn't be
strictly sound, anyway). If we get a working implementation up and running
and find that there are real-world issues that come up when compiling large
bodies of open source code, then we can reconsider things.

On Thu, Aug 6, 2015 at 7:52 AM, Matthew Woehlke <mwoehlke.floss@gmail.com>
 wrote:

> these two examples need to work:
>
>   template <typename T> foo(T const&);
>   foo<void>();
>
>   template <typename T> class Bar { void bar(T const&); };
>   Bar{}.bar();
>
> The latter you'll recall is specifically needed to avoid specializing
> std::future.
>

I don't think either of those strictly need to work. I think they're both
technically incorrect and we'd only support such invocation to ease
transition. To be clear, for the latter you mean for promise's set_value()?
I don't think it's true that that is necessary. Here are a couple of
options:

//////////
template<class T>
struct promise {
  // ...
  void set_value(T&&);
  void set_value(const T&);
  // ...
};
//////////

This is effectively the current promise default specification. If void is a
regular type, you'd commonly call it as:

//////////
your_promise.set_value(void());
//or, or likely in generic code
your_promise.set_value(foo()); // assume foo returns void
//////////

If we do nothing else, then this would means users would need to break
code. If we use the "empty potentially means default-constructed-void"
approach, then you could also just call set_value as
"your_promise.set_value()" and it would just work, because unary void
candidates exist.

I am not a huge fan of either of those. There are two, more simple options,
that wouldn't muck with overload resolution rules:

//////////
template<class T>
struct promise {
  // ...
  void set_value(T&& = T());
  void set_value(const T& = T());
  // ...
};
//////////

Here, we'd just say that you can call "your_promise.set_value()" in all of
the default cases, including the void case. We just have a default argument.

Finally, and I like this quite a bit less but I include it to be complete,
we could realistically do:

//////////
struct lazy_void { using type = void; }; // implementation detail

template<class T>
struct promise {
  // ...
  void set_value(T&& = typename std::conditional_t<is_void<T>::value,
lazy_void, void>::type());
  void set_value(const T&);
  // ...
};
//////////

This is sort of gross because we only have the default for void, but it
would only be "required" so that fewer people would have to update their
calling code. As nasty as it is, even this I consider to be a better idea
than allowing strictly no arguments being passed in to potentially match a
unary function.

Note also that we MUST either allow 'void bar(); foo(bar())' to call a
> 'foo()', or else provide something like std::void_t, or we have not
> solved the generic programming case where a template calls a function
> that has only explicit overloads but is not itself templated.


I don't see why you feel that is the case. In the generic case the
signatures would just match. We'd only potentially want to address other
cases to ease API transitions, for instance, where some APIs still have the
special-casing but are called from code that removed the special casing or
the reverse. That, and simply if we want to minimize breakage of existing
non-generic code when a dependency gets updated to remove special casing. I
think we should err on the side of being conservative here and not try to
introduce unsound workaround to make this work, since they necessarily
affect overload resolution in some way, and that is a hairy beast.

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
hu, Aug 6, 2015 at 7:52 AM, Matthew Woehlke <span dir=3D"ltr">&lt;<a href=
=3D"mailto:mwoehlke.floss@gmail.com" target=3D"_blank">mwoehlke.floss@gmail=
..com</a>&gt;</span> wrote:<blockquote class=3D"gmail_quote" style=3D"margin=
:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Honestly, I&#39;m =
not entirely convinced that I&#39;m opposed to the idea,<br>
although neither am I entirely convinced of the necessity. My main<br>
concerns are about not changing the meaning of existing code and<br>
behaving sensibly w.r.t. empty returns and argument lists. I won&#39;t<br>
rehash all of those, but a few cases in particular:<br>
<br>
=C2=A0 template &lt;typename T&gt; foo(T const&amp;);<br>
=C2=A0 foo&lt;void&gt;(); // should work<br></blockquote><div><br></div><di=
v>I actually don&#39;t think it&#39;s strictly sound for that to work even =
though we might want it. The only reason to allow it is to ease the transit=
ion of APIs. Initially, I thought it would be very useful and was championi=
ng that, but the more I formalize things, the more fragile and also less us=
eful it seems. There are more sound alternatives that API developers could =
make when updating their code that eases the transition for users (temporar=
ily adding a default for the API transition, for instance, if only for the =
void case). The main problem with supporting the case you&#39;ve shown is t=
hat, apart from it not being strictly logically sound, even though we can m=
ake it &quot;work,&quot; it can cause subtle breaks in existing code due to=
 more overloads being considered and more templates going through substitut=
ion when no argument is seemingly passed (you&#39;d now have to consider bo=
th nullary and unary cases for a single empty argument, just preferring nul=
lary as a better match).</div><div><br></div><div>FWIW, last night I starte=
d sketching out a proposal for my current thoughts on what a revised &quot;=
void&quot; type would be (sorry I hijacked this thread -- competing proposa=
ls are fine since this still looks controversial, I just really feel pretty=
 strongly about some of this stuff). I went through all of the changes that=
 we&#39;d hypothetically need to make to Core in order to have a very minim=
al &quot;void as a regular type&quot; proposal, and I did not touch on hand=
ling the above situation, nor did I touch on &quot;empty&quot; argument mea=
ning &quot;default-constructed-void&quot; at all, so unless others convince=
 me the other way, it might just serve as a note in my proposal without act=
ually being formally proposed. Without such changes and without a decision =
yet on how to represent a unary void function type when void is not depende=
nt, there are actually surprisingly minimal changes required for Core. I do=
n&#39;t have it in front of me, but there was only something like 5 or 6 ch=
anges to definitions (void is now a complete object type that is also a sca=
lar and has the operators associated with a regular type, subtle change to =
the conditional operator that likely needs another pass to make sure nothin=
g breaks, allowing void as a non-type template parameter type, and probably=
 one or two things I don&#39;t remember), and then there were about 30 remo=
vals in various places where &quot;void&quot; was explicitly mentioned due =
to those mentions now either being redundant or no longer true as a consequ=
ence of void being a complete, object type that is a scalar.</div><div><br>=
</div><div>Other things of note that came up were whether or not user-defin=
ed conversion to void should be allowed. Logically there isn&#39;t anything=
 wrong with it and it could hypothetically come up in generic code, but it&=
#39;s also a breaking change since people can currently cast expressions to=
 void in generic code such that they can safely use something like comma wi=
thout risking pulling in an overload. Similarly, if people can overload com=
ma for when exactly one of the operands is void, that has implications when=
 writing correct generic code, too -- as for why, it&#39;s for some similar=
 reasons as to why you&#39;d want to use std::addressof in generic code. My=
 current thoughts are to (unfortunately) leave these special-cased for now =
and address them separately.</div><div><br></div><div>Ultimately I think it=
&#39;s hard to figure out exactly what is okay to break and what is &quot;n=
ecessary&quot; for the transition until we hack together an implementation =
and actually fully examine all of the implications for the standard library=
 (such as possible removal of the void specialization from promise).</div><=
div><br></div><div>On Thu, Aug 6, 2015 at 7:52 AM, Matthew Woehlke=C2=A0<sp=
an dir=3D"ltr">&lt;<a href=3D"mailto:mwoehlke.floss@gmail.com" target=3D"_b=
lank">mwoehlke.floss@gmail.com</a>&gt;</span>=C2=A0wrote:<br></div><blockqu=
ote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc s=
olid;padding-left:1ex">=C2=A0 void bar();<br>
=C2=A0 auto x =3D bar(); // should work<br>
=C2=A0 void y =3D bar(); // should also work?<br></blockquote><div><br></di=
v><div>Sure, why not? What problem would this cause?</div><div><br></div><d=
iv>On Thu, Aug 6, 2015 at 7:52 AM, Matthew Woehlke=C2=A0<span dir=3D"ltr">&=
lt;<a href=3D"mailto:mwoehlke.floss@gmail.com" target=3D"_blank">mwoehlke.f=
loss@gmail.com</a>&gt;</span>=C2=A0wrote:<br></div><blockquote class=3D"gma=
il_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-lef=
t:1ex">What to do with something like this:<br>
<br>
=C2=A0 template &lt;typename Args...&gt; foo(Args const&amp;... args);<br>
=C2=A0 foo&lt;int, void, int&gt;( /* what can legally go here? */ );<br>
<br>
....is a much thornier question.<br></blockquote><div><br></div><div>I don&#=
39;t see an issue. void is just a regular type.You can call it as &quot;foo=
(1, void(), 3);&quot; for example. Any expression yielding void can be used=
 as that second argument, just like with other types. If supporting the &qu=
ot;empty argument meaning default-constructed-void&quot; possibility, you c=
ould also just have empty-space between the commas. Again though, I&#39;m n=
ot actually suggesting that in what I&#39;ve sketched out so far.</div><div=
><br></div><div>On Thu, Aug 6, 2015 at 7:52 AM, Matthew Woehlke=C2=A0<span =
dir=3D"ltr">&lt;<a href=3D"mailto:mwoehlke.floss@gmail.com" target=3D"_blan=
k">mwoehlke.floss@gmail.com</a>&gt;</span>=C2=A0wrote:<br></div><blockquote=
 class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc soli=
d;padding-left:1ex">...or if a log_success(void) exists (where that &#39;vo=
id&#39; may be<br>
dependent). Which, per above, can also be called as a zero-argument<br>
function. (I&#39;m not assuming that log_success(...) is templated.) Really=
,<br>
what I meant was that there exists an overload that can be called with a<br=
>
single void argument. A zero-argument overload would fit that bill. One<br>
taking a dependent-type void would also.<br></blockquote><div><br></div><di=
v>Ah, ok.</div><div>=C2=A0</div><div>On Thu, Aug 6, 2015 at 7:52 AM, Matthe=
w Woehlke=C2=A0<span dir=3D"ltr">&lt;<a href=3D"mailto:mwoehlke.floss@gmail=
..com" target=3D"_blank">mwoehlke.floss@gmail.com</a>&gt;</span>=C2=A0wrote:=
<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bord=
er-left:1px #ccc solid;padding-left:1ex">(Then there is the question of whi=
ch one is preferred in overload<br>
resolution. I guess if the call provides a void argument, then the<br>
dependent-type version should be preferred. On the flip side, should a<br>
zero-argument call ever call a &lt;void&gt; function? Do we provide somethi=
ng<br>
like std::void_t to allow a non-template overload taking a void argument?)<=
br></blockquote><div><br></div><div>These issues don&#39;t exit when void i=
s an object type and there is no collapsing or anything. If a function take=
s a void argument and it doesn&#39;t have a default, then you simply must p=
ass a void expression. If a function takes no arguments, you simply cannot =
pass void. They are distinct and incompatible cases. Right now we only have=
 a way of representing the nullary case, so the transition could have hiccu=
ps, but we&#39;d end up with something that is sound. The &quot;empty possi=
bly meaning default-construct void&quot; thing straddles the line and also =
attempts to address this, but I find it less and less appealing. The rule w=
ould (effectively) have been that if you pass in no argument such as invoki=
ng it as &quot;foo()&quot;, then the overloads that are considered are the =
combined set of both &quot;foo(/*truly no arg*/)&quot; and &quot;foo(void()=
))&quot;, preferring nullary versions as a better match when there are mult=
iple viable candidates. Rather than going down this route, though, I think =
the conservative approach is to not muck with overload resolution as it is =
scary and fragile (and this wouldn&#39;t be strictly sound, anyway). If we =
get a working implementation up and running and find that there are real-wo=
rld issues that come up when compiling large bodies of open source code, th=
en we can reconsider things.</div><div><br></div><div>On Thu, Aug 6, 2015 a=
t 7:52 AM, Matthew Woehlke=C2=A0<span dir=3D"ltr">&lt;<a href=3D"mailto:mwo=
ehlke.floss@gmail.com" target=3D"_blank">mwoehlke.floss@gmail.com</a>&gt;</=
span>=C2=A0wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"margi=
n:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">these two example=
s need to work:<br>
<br>
=C2=A0 template &lt;typename T&gt; foo(T const&amp;);<br>
=C2=A0 foo&lt;void&gt;();<br>
<br>
=C2=A0 template &lt;typename T&gt; class Bar { void bar(T const&amp;); };<b=
r>
=C2=A0 Bar{}.bar();<br>
<br>
The latter you&#39;ll recall is specifically needed to avoid specializing<b=
r>
std::future.<br></blockquote><div><br></div><div>I don&#39;t think either o=
f those strictly need to work. I think they&#39;re both technically incorre=
ct and we&#39;d only support such invocation to ease transition. To be clea=
r, for the latter you mean for promise&#39;s set_value()? I don&#39;t think=
 it&#39;s true that that is necessary. Here are a couple of options:</div><=
div><br></div><div>//////////</div><div>template&lt;class T&gt;</div><div>s=
truct promise {</div><div>=C2=A0 // ...</div><div>=C2=A0 void set_value(T&a=
mp;&amp;);</div><div>=C2=A0 void set_value(const T&amp;);</div><div>=C2=A0 =
// ...</div><div>};</div><div>//////////</div><div><br></div><div>This is e=
ffectively the current promise default specification. If void is a regular =
type, you&#39;d commonly call it as:</div><div><br></div><div>//////////</d=
iv><div>your_promise.set_value(void());</div><div>//or, or likely in generi=
c code</div><div>your_promise.set_value(foo()); // assume foo returns void<=
/div><div>//////////</div><div><br></div><div>If we do nothing else, then t=
his would means users would need to break code. If we use the &quot;empty p=
otentially means default-constructed-void&quot; approach, then you could al=
so just call set_value as &quot;your_promise.set_value()&quot; and it would=
 just work, because unary void candidates exist.</div><div><br></div><div>I=
 am not a huge fan of either of those. There are two, more simple options, =
that wouldn&#39;t muck with overload resolution rules:</div><div><br></div>=
<div><div>//////////</div><div>template&lt;class T&gt;</div><div>struct pro=
mise {</div><div>=C2=A0 // ...</div><div>=C2=A0 void set_value(T&amp;&amp; =
=3D T());</div><div>=C2=A0 void set_value(const T&amp; =3D T());</div><div>=
=C2=A0 // ...</div><div>};</div><div>//////////</div></div><div><br></div><=
div>Here, we&#39;d just say that you can call &quot;your_promise.set_value(=
)&quot; in all of the default cases, including the void case. We just have =
a default argument.</div><div><br></div><div>Finally, and I like this quite=
 a bit less but I include it to be complete, we could realistically do:</di=
v><div><br></div><div>//////////</div><div>struct lazy_void { using type =
=3D void; }; // implementation detail</div><div><br></div><div><div>templat=
e&lt;class T&gt;</div><div>struct promise {</div><div>=C2=A0 // ...</div><d=
iv>=C2=A0 void set_value(T&amp;&amp; =3D typename std::conditional_t&lt;is_=
void&lt;T&gt;::value, lazy_void, void&gt;::type());</div>=C2=A0 void set_va=
lue(const T&amp;);<div>=C2=A0 // ...</div><div>};</div></div><div>/////////=
/</div><div><br></div><div>This is sort of gross because we only have the d=
efault for void, but it would only be &quot;required&quot; so that fewer pe=
ople would have to update their calling code. As nasty as it is, even this =
I consider to be a better idea than allowing strictly no arguments being pa=
ssed in to potentially match a unary function.</div><div><br></div><blockqu=
ote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc s=
olid;padding-left:1ex">Note also that we MUST either allow &#39;void bar();=
 foo(bar())&#39; to call a<br>
&#39;foo()&#39;, or else provide something like std::void_t, or we have not=
<br>
solved the generic programming case where a template calls a function<br>
that has only explicit overloads but is not itself templated.</blockquote><=
div><br></div><div>I don&#39;t see why you feel that is the case. In the ge=
neric case the signatures would just match. We&#39;d only potentially want =
to address other cases to ease API transitions, for instance, where some AP=
Is still have the special-casing but are called from code that removed the =
special casing or the reverse. That, and simply if we want to minimize brea=
kage of existing non-generic code when a dependency gets updated to remove =
special casing. I think we should err on the side of being conservative her=
e and not try to introduce unsound workaround to make this work, since they=
 necessarily affect overload resolution in some way, and that is a hairy be=
ast.</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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a113cd18cafcb21051ca9538b--

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Thu, 06 Aug 2015 15:58:38 -0400
Raw View
On 2015-08-06 15:14, Matt Calabrese wrote:
> On Thu, Aug 6, 2015 at 7:52 AM, Matthew Woehlke wrote:
>> Honestly, I'm not entirely convinced that I'm opposed to the idea,
>> although neither am I entirely convinced of the necessity. My main
>> concerns are about not changing the meaning of existing code and
>> behaving sensibly w.r.t. empty returns and argument lists. I won't
>> rehash all of those, but a few cases in particular:
>>
>>   template <typename T> foo(T const&);
>>   foo<void>(); // should work
>
> I actually don't think it's strictly sound for that to work even though we
> might want it. The only reason to allow it is to ease the transition of
> APIs.

Well, let's visit the previously given example, std::future:

  template <typename T> class future
  {
    void set_value(T const&);
  }

  void my_async_func(future<void>& f)
  {
    // do work
    f.set_future( /* um...?? */ );
  }

Currently, we specialize classes like this so that when T == void, we
can provide zero-argument flavors of certain methods where, as in the
above example, an argument makes no sense in the T == void case.

If we don't allow eliding of a single [CV-qualified] void argument, how
are we supposed to call such functions? 'set_value({});'?
'set_value(void);'? Declare a useless 'void' variable to use as the
argument? IMO all of these are ugly. They also prevent trivial removal
of an existing specialization for void (e.g. in some existing class that
has the same "issue" as std::future).

> There are more sound alternatives that API developers
> could make when updating their code that eases the transition for users
> (temporarily adding a default for the API transition, for instance, if only
> for the void case).

....but now we are specializing again, which defeats the purpose! (Or
adding a default to ALL instantiations, which is dubious at best.)

> The main problem with supporting the case you've shown
> is that, apart from it not being strictly logically sound, even though we
> can make it "work," it can cause subtle breaks in existing code due to more
> overloads being considered and more templates going through substitution
> when no argument is seemingly passed (you'd now have to consider both
> nullary and unary cases for a single empty argument, just preferring
> nullary as a better match).

This is why I suggested in the previous e-mail *not* triggering
instantiation of a one-void-argument from an zero-argument call.

That is, this is still an error:

  // error; no match for 'foo()'; candidates are 'foo(typename const&)'
  template <typename T> void foo(T const&);
  foo();

....but these are not:

  // okay; explicit instantiation
  template <typename T> foo(T const&);
  foo<void>();

  // okay; bar() is not templated within the calling context (Bar<void>)
  template <typename T> class Bar { void bar(T const&); };
  Bar<void>{}.bar();

Presumably, this is also not an error:

  template <typename T> void foo(T const&);
  foo(foo(1));

> On Thu, Aug 6, 2015 at 7:52 AM, Matthew Woehlke wrote:
>>   void bar();
>>   auto x = bar(); // should work
>>   void y = bar(); // should also work?
>
> Sure, why not? What problem would this cause?

It's more potentially controversial, but I'd agree; allow assignment to
void whether deduced or explicit.

Question: does a void local have storage? (I want to say "no", and that
correspondingly, while taking the address of a void local is permitted,
the result is nullptr.)

>> (Then there is the question of which one is preferred in overload
>> resolution. I guess if the call provides a void argument, then the
>> dependent-type version should be preferred. On the flip side, should a
>> zero-argument call ever call a <void> function? Do we provide something
>> like std::void_t to allow a non-template overload taking a void argument?)
>
> These issues don't exit when void is an object type and there is no
> collapsing or anything.

But we *do* have collapsing. At least, we agreed that we don't want to
break the case 'void foo()' == 'void foo(void)'?

That being the case, how do you express a function taking a single
argument of type 'void'? One of the niceties of only allowing void
function arguments in deduced contexts is that you can pull some hand
waving and say that void is "really" some type that behaves like void,
but always "consumes" an argument slot.

In either case, there remain questions of how to handle having both a
zero-argument function and a one-argument function taking 'void'.


>> Note also that we MUST either allow 'void bar(); foo(bar())' to call a
>> 'foo()', or else provide something like std::void_t, or we have not
>> solved the generic programming case where a template calls a function
>> that has only explicit overloads but is not itself templated.
>
> I don't see why you feel that is the case. In the generic case the
> signatures would just match.

  void overloaded();
  void overloaded(int);
  void overloaded(double);
  // ...etc.

  template <typename T> generic(T const& value)
  {
    overloaded(value);
  }

  generic<void>(...); // uh oh...

I'm unconvinced this never occurs in practice. (Remember, too, that you
didn't provide a way to declare 'overloaded(void)' as a one-argument
function.)

--
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: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Thu, 6 Aug 2015 13:00:04 -0700
Raw View
--001a1142da9c27b653051ca9f785
Content-Type: text/plain; charset=UTF-8

On Thu, Aug 6, 2015 at 12:14 PM, Matt Calabrese <calabrese@google.com>
wrote:
>
> I am not a huge fan of either of those. There are two, more simple
> options, that wouldn't muck with overload resolution rules:
>
> //////////
> template<class T>
> struct promise {
>   // ...
>   void set_value(T&& = T());
>   void set_value(const T& = T());
>   // ...
> };
> //////////
>
> Here, we'd just say that you can call "your_promise.set_value()" in all of
> the default cases, including the void case. We just have a default argument.
>


Woops. To be clear, the default would only be for the r-value reference
overload to avoid ambiguities. The similar code was correct in the later
example.

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
hu, Aug 6, 2015 at 12:14 PM, Matt Calabrese <span dir=3D"ltr">&lt;<a href=
=3D"mailto:calabrese@google.com" target=3D"_blank">calabrese@google.com</a>=
&gt;</span> wrote:<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 clas=
s=3D"gmail_extra"><div class=3D"gmail_quote"><div>I am not a huge fan of ei=
ther of those. There are two, more simple options, that wouldn&#39;t muck w=
ith overload resolution rules:</div><div><br></div><div><div>//////////</di=
v><div>template&lt;class T&gt;</div><div>struct promise {</div><div>=C2=A0 =
// ...</div><div>=C2=A0 void set_value(T&amp;&amp; =3D T());</div><div>=C2=
=A0 void set_value(const T&amp; =3D T());</div><div>=C2=A0 // ...</div><div=
>};</div><div>//////////</div></div><div><br></div><div>Here, we&#39;d just=
 say that you can call &quot;your_promise.set_value()&quot; in all of the d=
efault cases, including the void case. We just have a default argument.</di=
v></div></div></div></blockquote><div><br></div><div><br></div><div>Woops. =
To be clear, the default would only be for the r-value reference overload t=
o avoid ambiguities. The similar code was correct in the later example.</di=
v></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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a1142da9c27b653051ca9f785--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Thu, 6 Aug 2015 13:58:00 -0700
Raw View
--001a113cd18c54dba1051caac669
Content-Type: text/plain; charset=UTF-8

On Thu, Aug 6, 2015 at 12:58 PM, Matthew Woehlke <mwoehlke.floss@gmail.com>
wrote:
>
> If we don't allow eliding of a single [CV-qualified] void argument, how
> are we supposed to call such functions? 'set_value({});'?
>

I detailed it later in the reply. Also, to be clear, this is promise and
not future. future doesn't have set_value. There isn't special casing that
is required.

On Thu, Aug 6, 2015 at 12:58 PM, Matthew Woehlke <mwoehlke.floss@gmail.com>
 wrote:

> ...but now we are specializing again, which defeats the purpose! (Or
> adding a default to ALL instantiations, which is dubious at best.)
>

No, you'd only add a special case if you want to ease the transition of an
API for users. Completely new APIs would not do this at all. If you are
updating your API, you could just do this to avoid breaking user code. It
is not a requirement and doesn't affect the ability of generic code to
treat void like any other type.

On Thu, Aug 6, 2015 at 12:58 PM, Matthew Woehlke <mwoehlke.floss@gmail.com>
 wrote:

> This is why I suggested in the previous e-mail *not* triggering
> instantiation of a one-void-argument from an zero-argument call.
>
> That is, this is still an error:
>
>   // error; no match for 'foo()'; candidates are 'foo(typename const&)'
>   template <typename T> void foo(T const&);
>   foo();
>
> ...but these are not:
>
>   // okay; explicit instantiation
>   template <typename T> foo(T const&);
>   foo<void>();
>
>   // okay; bar() is not templated within the calling context (Bar<void>)
>   template <typename T> class Bar { void bar(T const&); };
>   Bar<void>{}.bar();
>
> Presumably, this is also not an error:
>
>   template <typename T> void foo(T const&);
>   foo(foo(1));
>

But then users of the API would need to special-case for void in those
places, which is especially problematic if the "user" is more generic code
that may or may not be dealing with void as a dependent type. As long as we
treat void somehow differently with respect to overload resolution, we will
always have these kinds of subtleties, so IMO we shouldn't try to do it.
The idea isn't really sound or consistent, so we probably shouldn't do it
just to aid in a transition. The most direct way to be sure that we do not
hurt new generic code in subtle ways (or break old code in subtle ways) is
to have void simply be a regular type and not change anything regarding
overload resolution.

On Thu, Aug 6, 2015 at 12:58 PM, Matthew Woehlke <mwoehlke.floss@gmail.com>
 wrote:

> Question: does a void local have storage? (I want to say "no", and that
> correspondingly, while taking the address of a void local is permitted,
> the result is nullptr.)
>

It should in the language as it is today because it should behave exactly
as all other types in the language. It is effectively equivalent to struct
void {}; with comparison operators. Some have suggested that sizeof report
0 (notably Sean), which IMO is just too big of a change to the language as
a whole and has a huge number of implications touching on aliasing rules,
arrays, pointers as iterators into arrays, etc. It would also make void no
longer able to be used in the same way as other types in generic code. If
we ever wanted to allow it to truly be that sizeof(void) == 0, then IMO
that is orthogonal to void itself and is the realm of a separate proposal
that should not at all be unique to void. In other words, any user-defined
type with no members should be able to do the same (you'd probably need to
opt-in for the possibility, realistically, otherwise you could REALLY break
existing code in nasty ways). That is a very big deal and a huge effort to
do correctly and I'm definitely not the person to do it. You really need a
compiler expert to understand all of the intricacies, and honestly, the
gains aren't very much at all. Already the storage can be optimized away
when it is not observed (such as if it is only on the stack, if it is just
passed around by value in a given context, etc.). For now, the size is
simply not explicitly mentioned and so it has the rules of any other type.
That is to say, an implementation can make it whatever size that they want
>= 1, just like any user-defined struct that is empty. It's an
implementation detail.

 On Thu, Aug 6, 2015 at 12:58 PM, Matthew Woehlke <mwoehlke.floss@gmail.com>
 wrote:

> But we *do* have collapsing. At least, we agreed that we don't want to
> break the case 'void foo()' == 'void foo(void)'?
>

That's different from collapsing and it's just to not break existing code.
It only happens when the void parameter type is not a dependent type. If
the void parameter type is a dependent type, then it is different type from
"void ()". In other words, a function that takes a single void parameter is
still a different function type from a function that takes no parameters,
it's just that syntactically we can't realistically represent it using the
natural syntax when void is not a dependent type because it would break a
huge amount of existing code that depends on the previous meaning (so we'd
need a different syntax when void isn't dependent there). The reason why we
can support it when void is dependent is because that is currently not
valid in C++ as it is today, meaning there are much fewer concerns about
code breakage. It would only potentially break hypothetical SFINAE
exploits. So, in generic code, the syntax works and represents a function
taking a single void parameter as long as that parameter type is dependent.
I have the full description written up at home as it would be proposed in
the standard and clarifies things more exactly than I have done here.
Ideally we would deprecate "void foo(void)" meaning nullary, but I
anticipate that even such deprecation can see push-back.

On Thu, Aug 6, 2015 at 12:58 PM, Matthew Woehlke <mwoehlke.floss@gmail.com>
 wrote:

> That being the case, how do you express a function taking a single
> argument of type 'void'? One of the niceties of only allowing void
> function arguments in deduced contexts is that you can pull some hand
> waving and say that void is "really" some type that behaves like void,
> but always "consumes" an argument slot.
>

It's still up in the air. My original suggestion was:

void foo(explicit void);

Another suggestion was to just state that it is unary if you give the
parameter a name (which is currently illegal). This has a benefit of not
affecting the language grammar, though it is a little more subtle and less
obvious when just making a type. For instance:

// Here you'd have to use a name, even though people don't
// normally give names there.
std::function<void(void a)> foo;

Right now, the state of my sketched out proposal does not touch on the
topic, apart from explicitly disallowing a name until we decide on a
resolution.

On Thu, Aug 6, 2015 at 12:58 PM, Matthew Woehlke <mwoehlke.floss@gmail.com>
 wrote:

>   void overloaded();
>   void overloaded(int);
>   void overloaded(double);
>   // ...etc.
>
>   template <typename T> generic(T const& value)
>   {
>     overloaded(value);
>   }
>
>   generic<void>(...); // uh oh...
>
> I'm unconvinced this never occurs in practice. (Remember, too, that you
> didn't provide a way to declare 'overloaded(void)' as a one-argument
> function.)


It can in old code that hasn't been updated. In other words, if you write
generic code without void special cases, you wouldn't have this. The
nullary function with respect to the generic code would only exist as an
artifact of old generic code that had to special case for void. We'd only
want to address this if we wanted to ease the transition of APIs, but
handling it at all probably can't be done in a way that is fully sound, as
the suggested solutions (including my own suggestions) all have the
potential to break code in other subtle ways. I think the conservative
thing is to just accept that people need to update their code here.

To be clear, we do have a short list of some ways to represent a unary void
function declaration when void isn't dependent, we just haven't decided on
one yet. There absolutely does need to be a way to do it when void isn't
dependent though. IMO a proposal should not be accepted without it, so it
needs to be addressed.

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
hu, Aug 6, 2015 at 12:58 PM, Matthew Woehlke <span dir=3D"ltr">&lt;<a href=
=3D"mailto:mwoehlke.floss@gmail.com" target=3D"_blank">mwoehlke.floss@gmail=
..com</a>&gt;</span> wrote:<blockquote class=3D"gmail_quote" style=3D"margin=
:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
If we don&#39;t allow eliding of a single [CV-qualified] void argument, how=
<br>
are we supposed to call such functions? &#39;set_value({});&#39;?<br></bloc=
kquote><div><br></div><div>I detailed it later in the reply. Also, to be cl=
ear, this is promise and not future. future doesn&#39;t have set_value. The=
re isn&#39;t special casing that is required.</div><div><br></div><div>On T=
hu, Aug 6, 2015 at 12:58 PM, Matthew Woehlke=C2=A0<span dir=3D"ltr">&lt;<a =
href=3D"mailto:mwoehlke.floss@gmail.com" target=3D"_blank">mwoehlke.floss@g=
mail.com</a>&gt;</span>=C2=A0wrote:<br></div><blockquote class=3D"gmail_quo=
te" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"=
>...but now we are specializing again, which defeats the purpose! (Or<br>
adding a default to ALL instantiations, which is dubious at best.)<span cla=
ss=3D""><br></span></blockquote><div><br></div><div>No, you&#39;d only add =
a special case if you want to ease the transition of an API for users. Comp=
letely new APIs would not do this at all. If you are updating your API, you=
 could just do this to avoid breaking user code. It is not a requirement an=
d doesn&#39;t affect the ability of generic code to treat void like any oth=
er type.</div><div><br></div><div>On Thu, Aug 6, 2015 at 12:58 PM, Matthew =
Woehlke=C2=A0<span dir=3D"ltr">&lt;<a href=3D"mailto:mwoehlke.floss@gmail.c=
om" target=3D"_blank">mwoehlke.floss@gmail.com</a>&gt;</span>=C2=A0wrote:<b=
r></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border=
-left:1px #ccc solid;padding-left:1ex">This is why I suggested in the previ=
ous e-mail *not* triggering<br>
instantiation of a one-void-argument from an zero-argument call.<br>
<br>
That is, this is still an error:<br>
<br>
=C2=A0 // error; no match for &#39;foo()&#39;; candidates are &#39;foo(type=
name const&amp;)&#39;<br>
=C2=A0 template &lt;typename T&gt; void foo(T const&amp;);<br>
=C2=A0 foo();<br>
<br>
....but these are not:<br>
<br>
=C2=A0 // okay; explicit instantiation<br>
<span class=3D"">=C2=A0 template &lt;typename T&gt; foo(T const&amp;);<br>
=C2=A0 foo&lt;void&gt;();<br>
<br>
</span>=C2=A0 // okay; bar() is not templated within the calling context (B=
ar&lt;void&gt;)<br>
<span class=3D"">=C2=A0 template &lt;typename T&gt; class Bar { void bar(T =
const&amp;); };<br>
</span>=C2=A0 Bar&lt;void&gt;{}.bar();<br>
<br>
Presumably, this is also not an error:<br>
<br>
=C2=A0 template &lt;typename T&gt; void foo(T const&amp;);<br>
=C2=A0 foo(foo(1));<br></blockquote><div><br></div><div>But then users of t=
he API would need to special-case for void in those places, which is especi=
ally problematic if the &quot;user&quot; is more generic code that may or m=
ay not be dealing with void as a dependent type. As long as we treat void s=
omehow differently with respect to overload resolution, we will always have=
 these kinds of subtleties, so IMO we shouldn&#39;t try to do it. The idea =
isn&#39;t really sound or consistent, so we probably shouldn&#39;t do it ju=
st to aid in a transition. The most direct way to be sure that we do not hu=
rt new generic code in subtle ways (or break old code in subtle ways) is to=
 have void simply be a regular type and not change anything regarding overl=
oad resolution.</div><div><br></div><div>On Thu, Aug 6, 2015 at 12:58 PM, M=
atthew Woehlke=C2=A0<span dir=3D"ltr">&lt;<a href=3D"mailto:mwoehlke.floss@=
gmail.com" target=3D"_blank">mwoehlke.floss@gmail.com</a>&gt;</span>=C2=A0w=
rote:<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex=
;border-left:1px #ccc solid;padding-left:1ex">
Question: does a void local have storage? (I want to say &quot;no&quot;, an=
d that<br>
correspondingly, while taking the address of a void local is permitted,<br>
the result is nullptr.)<br></blockquote><div><br></div><div>It should in th=
e language as it is today because it should behave exactly as all other typ=
es in the language. It is effectively equivalent to struct void {}; with co=
mparison operators. Some have suggested that sizeof report 0 (notably Sean)=
, which IMO is just too big of a change to the language as a whole and has =
a huge number of implications touching on aliasing rules, arrays, pointers =
as iterators into arrays, etc. It would also make void no longer able to be=
 used in the same way as other types in generic code. If we ever wanted to =
allow it to truly be that sizeof(void) =3D=3D 0, then IMO that is orthogona=
l to void itself and is the realm of a separate proposal that should not at=
 all be unique to void. In other words, any user-defined type with no membe=
rs should be able to do the same (you&#39;d probably need to opt-in for the=
 possibility, realistically, otherwise you could REALLY break existing code=
 in nasty ways). That is a very big deal and a huge effort to do correctly =
and I&#39;m definitely not the person to do it. You really need a compiler =
expert to understand all of the intricacies, and honestly, the gains aren&#=
39;t very much at all. Already the storage can be optimized away when it is=
 not observed (such as if it is only on the stack, if it is just passed aro=
und by value in a given context, etc.). For now, the size is simply not exp=
licitly mentioned and so it has the rules of any other type. That is to say=
, an implementation can make it whatever size that they want &gt;=3D 1, jus=
t like any user-defined struct that is empty. It&#39;s an implementation de=
tail.</div><div><br></div><div>=C2=A0On Thu, Aug 6, 2015 at 12:58 PM, Matth=
ew Woehlke=C2=A0<span dir=3D"ltr">&lt;<a href=3D"mailto:mwoehlke.floss@gmai=
l.com" target=3D"_blank">mwoehlke.floss@gmail.com</a>&gt;</span>=C2=A0wrote=
:</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-=
left:1px #ccc solid;padding-left:1ex">But we *do* have collapsing. At least=
, we agreed that we don&#39;t want to<br>
break the case &#39;void foo()&#39; =3D=3D &#39;void foo(void)&#39;?<br></b=
lockquote><div><br></div><div>That&#39;s different from collapsing and it&#=
39;s just to not break existing code. It only happens when the void paramet=
er type is not a dependent type. If the void parameter type is a dependent =
type, then it is different type from &quot;void ()&quot;. In other words, a=
 function that takes a single void parameter is still a different function =
type from a function that takes no parameters, it&#39;s just that syntactic=
ally we can&#39;t realistically represent it using the natural syntax when =
void is not a dependent type because it would break a huge amount of existi=
ng code that depends on the previous meaning (so we&#39;d need a different =
syntax when void isn&#39;t dependent there). The reason why we can support =
it when void is dependent is because that is currently not valid in C++ as =
it is today, meaning there are much fewer concerns about code breakage. It =
would only potentially break hypothetical SFINAE exploits. So, in generic c=
ode, the syntax works and represents a function taking a single void parame=
ter as long as that parameter type is dependent. I have the full descriptio=
n written up at home as it would be proposed in the standard and clarifies =
things more exactly than I have done here. Ideally we would deprecate &quot=
;void foo(void)&quot; meaning nullary, but I anticipate that even such depr=
ecation can see push-back.</div><div><br></div><div>On Thu, Aug 6, 2015 at =
12:58 PM, Matthew Woehlke=C2=A0<span dir=3D"ltr">&lt;<a href=3D"mailto:mwoe=
hlke.floss@gmail.com" target=3D"_blank">mwoehlke.floss@gmail.com</a>&gt;</s=
pan>=C2=A0wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"margin=
:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">That being the cas=
e, how do you express a function taking a single<br>
argument of type &#39;void&#39;? One of the niceties of only allowing void<=
br>
function arguments in deduced contexts is that you can pull some hand<br>
waving and say that void is &quot;really&quot; some type that behaves like =
void,<br>
but always &quot;consumes&quot; an argument slot.<br></blockquote><div><br>=
</div><div>It&#39;s still up in the air. My original suggestion was:</div><=
div><br></div><div>void foo(explicit void);</div><div><br></div><div>Anothe=
r suggestion was to just state that it is unary if you give the parameter a=
 name (which is currently illegal). This has a benefit of not affecting the=
 language grammar, though it is a little more subtle and less obvious when =
just making a type. For instance:</div><div><br></div><div>// Here you&#39;=
d have to use a name, even though people don&#39;t<br></div><div>// normall=
y give names there.</div><div>std::function&lt;void(void a)&gt; foo;</div><=
div><br></div><div>Right now, the state of my sketched out proposal does no=
t touch on the topic, apart from explicitly disallowing a name until we dec=
ide on a resolution.</div><div>=C2=A0</div><div>On Thu, Aug 6, 2015 at 12:5=
8 PM, Matthew Woehlke=C2=A0<span dir=3D"ltr">&lt;<a href=3D"mailto:mwoehlke=
..floss@gmail.com" target=3D"_blank">mwoehlke.floss@gmail.com</a>&gt;</span>=
=C2=A0wrote:</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .=
8ex;border-left:1px #ccc solid;padding-left:1ex">=C2=A0 void overloaded();<=
br>
=C2=A0 void overloaded(int);<br>
=C2=A0 void overloaded(double);<br>
=C2=A0 // ...etc.<br>
<br>
=C2=A0 template &lt;typename T&gt; generic(T const&amp; value)<br>
=C2=A0 {<br>
=C2=A0 =C2=A0 overloaded(value);<br>
=C2=A0 }<br>
<br>
=C2=A0 generic&lt;void&gt;(...); // uh oh...<br>
<br>
I&#39;m unconvinced this never occurs in practice. (Remember, too, that you=
<br>
didn&#39;t provide a way to declare &#39;overloaded(void)&#39; as a one-arg=
ument<br>
function.)</blockquote><div><br></div><div>It can in old code that hasn&#39=
;t been updated. In other words, if you write generic code without void spe=
cial cases, you wouldn&#39;t have this. The nullary function with respect t=
o the generic code would only exist as an artifact of old generic code that=
 had to special case for void. We&#39;d only want to address this if we wan=
ted to ease the transition of APIs, but handling it at all probably can&#39=
;t be done in a way that is fully sound, as the suggested solutions (includ=
ing my own suggestions) all have the potential to break code in other subtl=
e ways. I think the conservative thing is to just accept that people need t=
o update their code here.</div><div><br></div><div>To be clear, we do have =
a short list of some ways to represent a unary void function declaration wh=
en void isn&#39;t dependent, we just haven&#39;t decided on one yet. There =
absolutely does need to be a way to do it when void isn&#39;t dependent tho=
ugh. IMO a proposal should not be accepted without it, so it needs to be ad=
dressed.</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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a113cd18c54dba1051caac669--

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Thu, 06 Aug 2015 17:36:13 -0400
Raw View
On 2015-08-06 16:58, Matt Calabrese wrote:
> On Thu, Aug 6, 2015 at 12:58 PM, Matthew Woehlke wrote:
>> This is why I suggested in the previous e-mail *not* triggering
>> instantiation of a one-void-argument from an zero-argument call.
>>
>> That is, this is still an error:
>>
>>   // error; no match for 'foo()'; candidates are 'foo(typename const&)'
>>   template <typename T> void foo(T const&);
>>   foo();
>>
>> ...but these are not:
>>
>>   // okay; explicit instantiation
>>   template <typename T> foo(T const&);
>>   foo<void>();
>>
>>   // okay; bar() is not templated within the calling context (Bar<void>)
>>   template <typename T> class Bar { void bar(T const&); };
>>   Bar<void>{}.bar();
>>
>> Presumably, this is also not an error:
>>
>>   template <typename T> void foo(T const&);
>>   foo(foo(1));
>
> But then users of the API would need to special-case for void in those
> places

Why? You still *can* pass an explicit void argument. You aren't
*required* to do so; you can pass no arguments at all.

In fact, the only idea here is that if no 'foo()' exists, but a
'foo(magical_void_type)' *is already instantiated* (note "is already",
not "can be"), 'foo()' can/will call the latter.

What about the opposite case? Do we agree that this should work?

  void foo();
  foo(foo());

>> how do you express a function taking a single argument of type 'void'?
>
> Another suggestion was to just state that it is unary if you give the
> parameter a name (which is currently illegal).

Ick :-). Given that 'void foo(int);' and 'void foo(int i);' are
currently equivalent, I'd rather not go making 'void foo(void);' and
'void foo(void i);' mean something different...

>>   void overloaded();
>>   void overloaded(int);
>>   void overloaded(double);
>>   // ...etc.
>>
>>   template <typename T> generic(T const& value)
>>   {
>>     overloaded(value);
>>   }
>>
>>   generic<void>(...); // uh oh...
>>
>> I'm unconvinced this never occurs in practice. (Remember, too, that you
>> didn't provide a way to declare 'overloaded(void)' as a one-argument
>> function.)
>
> It can in old code that hasn't been updated. In other words, if you write
> generic code without void special cases, you wouldn't have this.

....so, basically, you are saying that I will be required to add a
'overload(really_void) { overload(); }' now? :-(

It occurs to me that it would be a useful exercise to implement this
change in some compiler and then compile some large projects that
already contain a lot of generic code (possibly removing void
specializations first)...

--
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 Stone <deusexsophismata@gmail.com>
Date: Sun, 27 Sep 2015 18:48:32 -0700 (PDT)
Raw View
------=_Part_972_1926969739.1443404912590
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

I think there is a lot of confusion over terminology here, so it might make=
 sense to explain it in terms of C++.

struct unit_type {
 unit_type() =3D default;
};

unit_type has exactly one possible state. If you have an instance of unit_t=
ype, you know everything about it from the type.

struct zero_type {
 zero_type() =3D delete;
};

zero_type has no possible states. You cannot have an instance of zero_type.=
 A function that returns zero_type is similar to a function declared with [=
[noreturn]].

Variants are called "sum types" because the number of states in a variant i=
s the sum of all possible states of each type. So variant<bool, zero_type> =
has two possible states (2 + 0) and is functionally equivalent to variant<b=
ool>. variant<bool, unit_type> has three possible states (2 + 1).

Classes are product types.

struct s {
 bool a;
 bool b;
};

This has four possible states. false + false, false + true, true + false, t=
rue + true =3D=3D 4 states. There are two states for a and two for b, givin=
g us 2 * 2 =3D=3D 4.

struct t {
 bool a;
 unit_type b;
};

This has two possible states, just like a plain bool (2 * 1). That "extra" =
state of b doesn't actually change anything.

struct u {
 bool a;
 zero_type b;
};

This has zero possible states (2 * 0). You cannot create an instance of u b=
ecause you cannot create an instance of zero_type. This is why Paul was say=
ing that std::tuple<void> should be the equivalent of void. Functionally, s=
td::tuple<zero_type> is identical to zero_type.

Right now, void is something in the middle of these two types. We can consi=
der it to be much like unit_type, but with a few special rules.

1) Functions that return void have a special rule that constructing a tempo=
rary void is implied by just `return;`, and if you fall off the end of the =
function, behavior is defined as though you had said return.

2) All pointer types are implicitly convertible to void *. This is almost a=
s though all pointer types have operator void *() defined (except the synta=
x `pointer.operator void *()` is invalid), or maybe you can think of it as =
being as if all types implicitly inherit from void (except std::is_base_of<=
void, T>::value is false for every T, even void).

3) You cannot dereference void * to form void &.

4) sizeof(void) is a compile-time error.

5) void behaves as though it were zero_type when you try to create it any o=
ther way (global variable, local variable, member variable, or function par=
ameter). It behaves as though it were unit_type when you return it from fun=
ctions, but with special rules as outlined in 1.

6) A function can take a single parameter of type void, and it is the same =
as a function that takes no parameters.

7) A function can only accept a single void parameter or an arbitrary numbe=
r of non-void parameters.

Note that making void be the zero_type breaks current code because it makes=
 void suddenly not able to do something. Making void the unit_type adds fun=
ctionality. It does not limit the theoretical completeness of C++ because v=
oid is already not the zero_type, and we can trivially define the zero_type=
 as I did above.

One of the design goals of C++ was that anything a built-in type can do, a =
user-defined type can do. To me, that means that the fewer special-case typ=
es that exist in C++, the closer we are to that goal (and I consider that a=
 good thing). One way to measure how close we are to that goal is to see if=
 we can implement the built-in types using C++. One way to get closer to th=
at goal (and to simplify the language) is to fix anything that we cannot im=
plement.

Allowing variables of void gets rid of the special case of 5. I believe tha=
t fixing 4 is a natural consequence of allowing variables of void. I agree =
with Matt that for consistency with the rest of the language, sizeof(void) =
should return 1 so that we are not adding in an extra special case. I would=
 definitely support considering allowing empty types to have sizeof(empty) =
=3D=3D 0, but that is a separate issue from allowing variables of type void=
..

One interesting question is what we do with void &. The same reasoning that=
 applies to void variables applies to references to void, I believe. This s=
uggests that dereferencing void * gives void &, which means that void & is =
a reference to anything.

In summary, I believe we can fix 3, 4, 5, and 7 without breaking any real c=
ode or introducing any new special cases (just eliminating them). Matt has =
talked about trying to fix 6, but doing so will either break existing code =
or add in new special cases. The new special cases are more limited than th=
e current special cases, but I don't know if that makes it better. We can t=
rivially fix 7, and that does just highlight the inconsistencies in 6, but =
it actually does seem kind of consistent with 1. void has some special case=
 rules that in some situations, it is implicitly default constructed. Tryin=
g to fix 1 or 2 would break a lot of code, and I don't think anyone is prop=
osing trying to eliminate those special cases.

--=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_972_1926969739.1443404912590--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Sun, 27 Sep 2015 23:27:09 -0700
Raw View
--001a1137bdd07dd49c0520c8c9d7
Content-Type: text/plain; charset=UTF-8

On Sun, Sep 27, 2015 at 6:48 PM, David Stone <deusexsophismata@gmail.com>
wrote:
>
> Note that making void be the zero_type breaks current code because it
> makes void suddenly not able to do something. Making void the unit_type
> adds functionality. It does not limit the theoretical completeness of C++
> because void is already not the zero_type, and we can trivially define the
> zero_type as I did above.
>
> One of the design goals of C++ was that anything a built-in type can do, a
> user-defined type can do. To me, that means that the fewer special-case
> types that exist in C++, the closer we are to that goal (and I consider
> that a good thing). One way to measure how close we are to that goal is to
> see if we can implement the built-in types using C++. One way to get closer
> to that goal (and to simplify the language) is to fix anything that we
> cannot implement.
>
> Allowing variables of void gets rid of the special case of 5. I believe
> that fixing 4 is a natural consequence of allowing variables of void. I
> agree with Matt that for consistency with the rest of the language,
> sizeof(void) should return 1 so that we are not adding in an extra special
> case. I would definitely support considering allowing empty types to have
> sizeof(empty) == 0, but that is a separate issue from allowing variables of
> type void.
>
> One interesting question is what we do with void &. The same reasoning
> that applies to void variables applies to references to void, I believe.
> This suggests that dereferencing void * gives void &, which means that void
> & is a reference to anything.
>
> In summary, I believe we can fix 3, 4, 5, and 7 without breaking any real
> code or introducing any new special cases (just eliminating them). Matt has
> talked about trying to fix 6, but doing so will either break existing code
> or add in new special cases. The new special cases are more limited than
> the current special cases, but I don't know if that makes it better. We can
> trivially fix 7, and that does just highlight the inconsistencies in 6, but
> it actually does seem kind of consistent with 1. void has some special case
> rules that in some situations, it is implicitly default constructed. Trying
> to fix 1 or 2 would break a lot of code, and I don't think anyone is
> proposing trying to eliminate those special cases.


FWIW, I have a proposal for instantiable void (P0112 -- "Regular Void").
This is strictly for the language. If the changes are considered viable I
will further submit a proposal for library changes (removal of
std::promise/std::future specializations in a backwards-compatible manner).
In brief, the proposal presents void as a monostate type with size
unspecified though governed by existing C++ rules (I do mention that size
being 0 would be something of interest in the language in a more general
sense, but that it is out of scope of the proposal). void& is supported,
and everything else that you can do with other object types is supported as
well. This is not explicit in changes to the standard, but rather is
implied by making void an object type (more specifically, a scalar type).
There are quite a few changes to the standard, but almost all of them are
just removals of parts that say "and also void" or "except for void."

Regarding the breaking changes to "A function can take a single parameter
of type void, and it is the same as a function that takes no parameters."
my suggestion is, as was suggested by someone else in this thread, give the
void parameter a name, or use a cv qualified void type. This is backwards
compatible and does not change the current meaning of "void" in a parameter
list when the parameter is not dependent. The only hypothetical breaking
changes in this respect come from somewhat obscure SFINAE exploits when
void is dependent. I also suggest deprecating the existing meaning of void
appearing as a parameter type, with the intent being that we eventually
reclaim that syntax to mean a unary function taking void in some future
standard.

I will link to the proposal as soon as it is up. Included with it are some
of the alternatives mentioned as well as rationale for why I recommend the
options that are formally presented in the proposal.

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On S=
un, Sep 27, 2015 at 6:48 PM, David Stone <span dir=3D"ltr">&lt;<a href=3D"m=
ailto:deusexsophismata@gmail.com" target=3D"_blank">deusexsophismata@gmail.=
com</a>&gt;</span> wrote:<blockquote class=3D"gmail_quote" style=3D"margin:=
0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);=
border-left-style:solid;padding-left:1ex">
Note that making void be the zero_type breaks current code because it makes=
 void suddenly not able to do something. Making void the unit_type adds fun=
ctionality. It does not limit the theoretical completeness of C++ because v=
oid is already not the zero_type, and we can trivially define the zero_type=
 as I did above.<br>
<br>
One of the design goals of C++ was that anything a built-in type can do, a =
user-defined type can do. To me, that means that the fewer special-case typ=
es that exist in C++, the closer we are to that goal (and I consider that a=
 good thing). One way to measure how close we are to that goal is to see if=
 we can implement the built-in types using C++. One way to get closer to th=
at goal (and to simplify the language) is to fix anything that we cannot im=
plement.<br>
<br>
Allowing variables of void gets rid of the special case of 5. I believe tha=
t fixing 4 is a natural consequence of allowing variables of void. I agree =
with Matt that for consistency with the rest of the language, sizeof(void) =
should return 1 so that we are not adding in an extra special case. I would=
 definitely support considering allowing empty types to have sizeof(empty) =
=3D=3D 0, but that is a separate issue from allowing variables of type void=
..<br>
<br>
One interesting question is what we do with void &amp;. The same reasoning =
that applies to void variables applies to references to void, I believe. Th=
is suggests that dereferencing void * gives void &amp;, which means that vo=
id &amp; is a reference to anything.<br>
<br>
In summary, I believe we can fix 3, 4, 5, and 7 without breaking any real c=
ode or introducing any new special cases (just eliminating them). Matt has =
talked about trying to fix 6, but doing so will either break existing code =
or add in new special cases. The new special cases are more limited than th=
e current special cases, but I don&#39;t know if that makes it better. We c=
an trivially fix 7, and that does just highlight the inconsistencies in 6, =
but it actually does seem kind of consistent with 1. void has some special =
case rules that in some situations, it is implicitly default constructed. T=
rying to fix 1 or 2 would break a lot of code, and I don&#39;t think anyone=
 is proposing trying to eliminate those special cases.</blockquote><div><br=
></div><div>FWIW, I have a proposal for instantiable void=C2=A0<span style=
=3D"font-size:12.8px">(P0112 -- &quot;Regular Void&quot;). This is strictly=
 for the language. If the changes are considered viable I will further subm=
it a proposal for library changes (removal of std::promise/std::future spec=
ializations in a backwards-compatible manner). In brief, the proposal prese=
nts void as a monostate type with size unspecified though governed by exist=
ing C++ rules (I do mention that size being 0 would be something of interes=
t in the language in a more general sense, but that it is out of scope of t=
he proposal). void&amp; is supported, and everything else that you can do w=
ith other object types is supported as well. This is not explicit in change=
s to the standard, but rather is implied by making void an object type (mor=
e specifically, a scalar type). There are quite a few changes to the standa=
rd, but almost all of them are just removals of parts that say &quot;and al=
so void&quot; or &quot;except for void.&quot;</span></div><div><span style=
=3D"font-size:12.8px"><br></span></div><div><span style=3D"font-size:12.8px=
">Regarding the breaking changes to &quot;</span><span style=3D"font-size:1=
2.8px">A function can take a single parameter of type void, and it is the s=
ame as a function that takes no parameters.&quot; my suggestion is, as was =
suggested by someone else in this thread, give the void parameter a name, o=
r use a cv qualified void type. This is backwards compatible and does not c=
hange the current meaning of &quot;void&quot; in a parameter list when the =
parameter is not dependent. The only hypothetical breaking changes in this =
respect come from somewhat obscure SFINAE exploits when void is dependent. =
I also suggest deprecating the existing meaning of void appearing as a para=
meter type, with the intent being that we eventually reclaim that syntax to=
 mean a unary function taking void in some future standard.</span></div><di=
v><span style=3D"font-size:12.8px"><br></span></div><div><span style=3D"fon=
t-size:12.8px">I will link to the proposal as soon as it is up. Included wi=
th it are some of the alternatives mentioned as well as rationale for why I=
 recommend the options that are formally presented in the proposal.</span><=
/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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a1137bdd07dd49c0520c8c9d7--

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Wed, 30 Sep 2015 14:15:55 -0400
Raw View
On 2015-09-27 21:48, David Stone wrote:
> 1) Functions that return void have a special rule that constructing
> a temporary void is implied by just `return;`, and if you fall off
> the end of the function, behavior is defined as though you had said
> return.

Except no. There is no temporary constructed. *There is no returned object*.

Falling off the end of a function causes code execution to resume from
the call site, regardless of return type. For non-void functions, that's
UB, because you failed to initialize the returned object. For void
functions, there is no problem, because *there is no return object* to
be initialized.

Talk about states all you want... as long as you ignore the storage
question, your explanations are going to have problems.

> 4) sizeof(void) is a compile-time error.

....because a 'void' has no storage.

> 6) A function can take a single parameter of type void, and it is the
> same as a function that takes no parameters.

Right. Because a function takes a list of types, and 'void' is
explicitly a non-type. That is, the type list 'void' is exactly the type
list ''.

> Note that making void be the zero_type breaks current code because it makes void suddenly not able to do something.

How so? You can't construct a void, as there is nothing to be
constructed. What breaks?

> Making void the unit_type adds functionality.

....and breaks #1 and #6.

> One of the design goals of C++ was that anything a built-in type can do, a user-defined type can do.

That's a nice platitude, but if you're going to achieve that, you have
to either provide a way for the user to define a type that NEVER has
storage (which is of limited use), or else recognize that 'void' isn't a
type in the normal sense.

> I believe that fixing 4 is a natural consequence of allowing
> variables of void. I agree with Matt that for consistency with the
> rest of the language, sizeof(void) should return 1 so that we are not
> adding in an extra special case. I would definitely support
> considering allowing empty types to have sizeof(empty) == 0, but that
> is a separate issue from allowing variables of type void.

I would disagree. A 'void' has no storage. The only correct answers
therefore for 'sizeof(void)' are '0' or to disallow the question.

> void has some special case rules that in some situations, it is
> implicitly default constructed.

....and this is exactly the sort of thing I'm talking about when I say
your reasoning is flawed. A void *isn't* a value. Talking about a void
being constructed makes no sense.

--
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 Stone <david@doublewise.net>
Date: Wed, 30 Sep 2015 18:04:59 -0600
Raw View
--001a113ce59c4c63a30520ffccc2
Content-Type: text/plain; charset=UTF-8

On Wed, Sep 30, 2015 at 12:15 PM, Matthew Woehlke <mwoehlke.floss@gmail.com>
wrote:

> On 2015-09-27 21:48, David Stone wrote:
> > 1) Functions that return void have a special rule that constructing
> > a temporary void is implied by just `return;`, and if you fall off
> > the end of the function, behavior is defined as though you had said
> > return.
>
> Except no. There is no temporary constructed. *There is no returned
> object*.
>

Under this proposal there would be, and with the exceptions to general
types I listed, there is no difference.

Falling off the end of a function causes code execution to resume from
> the call site, regardless of return type. For non-void functions, that's
> UB, because you failed to initialize the returned object. For void
> functions, there is no problem, because *there is no return object* to
> be initialized.
>

You have undefined behavior specifically because you have failed to say
return. 6.6.3, paragraph 2:

"Flowing off the end of a function is equivalent to a return with no value;
this results in undefined behavior in a value-returning function."

This is separately called out as undefined behavior, not as part of using
an uninitialized variable.

> 4) sizeof(void) is a compile-time error.
>
> ...because a 'void' has no storage.
>

Do you believe that unit_type has storage and void does not?


>
> > Note that making void be the zero_type breaks current code because it
> makes void suddenly not able to do something.
>
> How so? You can't construct a void, as there is nothing to be
> constructed. What breaks?
>

You cannot return zero_type from a function because it cannot be
constructed.


>
> > Making void the unit_type adds functionality.
>
> ...and breaks #1 and #6.
>

I would keep those current exceptions in for void.


>
> > One of the design goals of C++ was that anything a built-in type can do,
> a user-defined type can do.
>
> That's a nice platitude, but if you're going to achieve that, you have
> to either provide a way for the user to define a type that NEVER has
> storage (which is of limited use), or else recognize that 'void' isn't a
> type in the normal sense.
>

empty_type doesn't have storage in any meaningful sense, unless you count
that sizeof(empty_type) >= 1. The idea behind this proposal is to make void
more of a normal type and get rid of some of these exceptions, because they
are not necessary and cause problems in real code.


Do you believe there is anything factually wrong about what I have said, or
only conceptually wrong? If you think I have said something factually
wrong, can you tell me how a conforming program can tell the difference
between an implementation that implements void like I said and one that
does not?

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On W=
ed, Sep 30, 2015 at 12:15 PM, Matthew Woehlke <span dir=3D"ltr">&lt;<a href=
=3D"mailto:mwoehlke.floss@gmail.com" target=3D"_blank">mwoehlke.floss@gmail=
..com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:=
1ex"><span class=3D"">On 2015-09-27 21:48, David Stone wrote:<br>
&gt; 1) Functions that return void have a special rule that constructing<br=
>
&gt; a temporary void is implied by just `return;`, and if you fall off<br>
&gt; the end of the function, behavior is defined as though you had said<br=
>
&gt; return.<br>
<br>
</span>Except no. There is no temporary constructed. *There is no returned =
object*.<br></blockquote><div><br></div><div>Under this proposal there woul=
d be, and with the exceptions to general types I listed, there is no differ=
ence.<br></div><br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0p=
x 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Falling off the end of a function causes code execution to resume from<br>
the call site, regardless of return type. For non-void functions, that&#39;=
s<br>
UB, because you failed to initialize the returned object. For void<br>
functions, there is no problem, because *there is no return object* to<br>
be initialized.<br></blockquote><div><br></div><div>You have undefined beha=
vior specifically because you have failed to say return. 6.6.3, paragraph 2=
:<br><br>&quot;Flowing off the end of a function is equivalent to a return =
with no value; this results in undefined behavior in a value-returning func=
tion.&quot;<br><br></div><div>This is separately called out as undefined be=
havior, not as part of using an uninitialized variable.<br></div><br><block=
quote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1=
px solid rgb(204,204,204);padding-left:1ex"><span class=3D"">
&gt; 4) sizeof(void) is a compile-time error.<br>
<br>
</span>...because a &#39;void&#39; has no storage.<br></blockquote><div><br=
></div><div>Do you believe that unit_type has storage and void does not?<br=
></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0=
px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<span class=3D""><br></span><span class=3D"">&gt; Note that making void be =
the zero_type breaks current code because it makes void suddenly not able t=
o do something.<br>
<br>
</span>How so? You can&#39;t construct a void, as there is nothing to be<br=
>
constructed. What breaks?<br></blockquote><div><br></div><div>You cannot re=
turn zero_type from a function because it cannot be constructed.<br></div><=
div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0=
px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<span class=3D""><br>
&gt; Making void the unit_type adds functionality.<br>
<br>
</span>...and breaks #1 and #6.<br></blockquote><div><br></div><div>I would=
 keep those current exceptions in for void.<br></div><div>=C2=A0</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">
<span class=3D""><br>
&gt; One of the design goals of C++ was that anything a built-in type can d=
o, a user-defined type can do.<br>
<br>
</span>That&#39;s a nice platitude, but if you&#39;re going to achieve that=
, you have<br>
to either provide a way for the user to define a type that NEVER has<br>
storage (which is of limited use), or else recognize that &#39;void&#39; is=
n&#39;t a<br>
type in the normal sense.<br></blockquote><div><br></div><div>empty_type do=
esn&#39;t have storage in any meaningful sense, unless you count that sizeo=
f(empty_type) &gt;=3D 1. The idea behind this proposal is to make void more=
 of a normal type and get rid of some of these exceptions, because they are=
 not necessary and cause problems in real code.<br></div></div><br><br><div=
>Do you believe there is anything factually wrong about what I have said, o=
r only conceptually wrong? If you think I have said something factually wro=
ng, can you tell me how a conforming program can tell the difference betwee=
n an implementation that implements void like I said and one that does not?=
<br></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&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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a113ce59c4c63a30520ffccc2--

.


Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Thu, 1 Oct 2015 11:00:00 -0700
Raw View
--001a1137bdd0d6355005210ed050
Content-Type: text/plain; charset=UTF-8

On Sun, Sep 27, 2015 at 11:27 PM, Matt Calabrese <calabrese@google.com>
wrote:
>
> FWIW, I have a proposal for instantiable void (P0112 -- "Regular Void").
> This is strictly for the language. If the changes are considered viable I
> will further submit a proposal for library changes (removal of
> std::promise/std::future specializations in a backwards-compatible manner).
> In brief, the proposal presents void as a monostate type with size
> unspecified though governed by existing C++ rules (I do mention that size
> being 0 would be something of interest in the language in a more general
> sense, but that it is out of scope of the proposal). void& is supported,
> and everything else that you can do with other object types is supported as
> well. This is not explicit in changes to the standard, but rather is
> implied by making void an object type (more specifically, a scalar type).
> There are quite a few changes to the standard, but almost all of them are
> just removals of parts that say "and also void" or "except for void."
>

There was apparently a document # collision. The proposal is now P0146.

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On S=
un, Sep 27, 2015 at 11:27 PM, Matt Calabrese <span dir=3D"ltr">&lt;<a href=
=3D"mailto:calabrese@google.com" target=3D"_blank">calabrese@google.com</a>=
&gt;</span> wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px=
 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-=
left-style:solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_ext=
ra"><div class=3D"gmail_quote"><div>FWIW, I have a proposal for instantiabl=
e void=C2=A0<span style=3D"font-size:12.8px">(P0112 -- &quot;Regular Void&q=
uot;). This is strictly for the language. If the changes are considered via=
ble I will further submit a proposal for library changes (removal of std::p=
romise/std::future specializations in a backwards-compatible manner). In br=
ief, the proposal presents void as a monostate type with size unspecified t=
hough governed by existing C++ rules (I do mention that size being 0 would =
be something of interest in the language in a more general sense, but that =
it is out of scope of the proposal). void&amp; is supported, and everything=
 else that you can do with other object types is supported as well. This is=
 not explicit in changes to the standard, but rather is implied by making v=
oid an object type (more specifically, a scalar type). There are quite a fe=
w changes to the standard, but almost all of them are just removals of part=
s that say &quot;and also void&quot; or &quot;except for void.&quot;</span>=
</div></div></div></div></blockquote><div><br></div><div>There was apparent=
ly a document # collision. The proposal is now P0146.</div></div></div></di=
v>

<p></p>

-- <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+unsubscribe@isocpp.org">std-proposa=
ls+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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a1137bdd0d6355005210ed050--

.


Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Fri, 02 Oct 2015 13:36:14 -0400
Raw View
On 2015-09-30 20:04, David Stone wrote:
> On Wed, Sep 30, 2015 at 12:15 PM, Matthew Woehlke wrote:
>> Falling off the end of a function causes code execution to resume from
>> the call site, regardless of return type. For non-void functions, that's
>> UB, because you failed to initialize the returned object. For void
>> functions, there is no problem, because *there is no return object* to
>> be initialized.
>
> You have undefined behavior specifically because you have failed to say
> return. 6.6.3, paragraph 2:
>
> "Flowing off the end of a function is equivalent to a return with no value;
> this results in undefined behavior in a value-returning function."
>
> This is separately called out as undefined behavior, not as part of using
> an uninitialized variable.

That could be read two ways. Given that it specifies "equivalent to a
return", that would imply that the compiler is required to ensure that
control flow at least returns properly (as I said); UB therefore arises
because the return value was not initialized.

Or you could read it that the UB means the compiler is allowed to permit
execution to continue with whatever code happens to follow the end of
the function.

In practice, I believe the former is usually (always?) the case.

>> 4) sizeof(void) is a compile-time error.
>>
>> ...because a 'void' has no storage.
>
> Do you believe that unit_type has storage and void does not?

A void does not have storage. A unit type as you described ('struct
unit_t {};') does have storage when instantiated. (Note that I'm not
talking about pointers-to-void, which are also a strange beast but
aren't related to the void "type" in the way any other pointer-to-type
relates to its associated type.)

>> How so? You can't construct a void, as there is nothing to be
>> constructed. What breaks?
>
> You cannot return zero_type from a function because it cannot be
> constructed.

Irrelevant. You aren't returning a type that cannot be constructed. You
aren't returning *anything*.

A function returns a list of values (which in C++ is currently
constrained to having size == 0 (void) or size == 1 (otherwise)). An
empty value list does not "contain" a zero-type. It's just *empty*.

'void' really isn't your zero_type, because zero_type as you defined it
is still a type. It really isn't a "type", period (in the C++ sense);
it's an *absence* of a type and/or entity.

> Do you believe there is anything factually wrong about what I have said, or
> only conceptually wrong? If you think I have said something factually
> wrong, can you tell me how a conforming program can tell the difference
> between an implementation that implements void like I said and one that
> does not?

It may be that an implementation as you propose is possible. However, I
consider that beside the point, because IMO what you want to do to void
makes it in ways even MORE exceptional than it is currently, and I'm
deeply concerned that trying to coerce void into being "a regular type"
results in a serious loss of what concepts can be expressed by the
language, even if that loss is not an immediate effect of your proposal.

In short, I believe your entire concept is akin removing '0' from the
set of integers. I hope I don't need to explain why that would be a bad
idea.

I like the idea of trying to make template programming easier in the
face of 'void'. I just don't agree that we should do it by removing the
notion of a non-type or by pretending that isn't what 'void' *is*.
Although the more I think about it, the more I'm not sure even of that
much. We're trying to solve a "zero or one" problem, when we really
should be trying to solve the problem that templates rely too heavily on
functions returning exactly one value, as opposed to any number of
values, whether that's zero, two, or fifty (or one).

--
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: Jens Maurer <Jens.Maurer@gmx.net>
Date: Fri, 02 Oct 2015 20:22:02 +0200
Raw View
On 10/02/2015 07:36 PM, Matthew Woehlke wrote:
> On 2015-09-30 20:04, David Stone wrote:

>> "Flowing off the end of a function is equivalent to a return with no value;
>> this results in undefined behavior in a value-returning function."
>>
>> This is separately called out as undefined behavior, not as part of using
>> an uninitialized variable.
>
> That could be read two ways. Given that it specifies "equivalent to a
> return", that would imply that the compiler is required to ensure that
> control flow at least returns properly (as I said); UB therefore arises
> because the return value was not initialized.
>
> Or you could read it that the UB means the compiler is allowed to permit
> execution to continue with whatever code happens to follow the end of
> the function.

Undefined behavior has no bounds, from a specification standpoint.
So, it doesn't make sense to discuss which behavior happens when
the standard prescribes undefined behavior.  Yes, formatting your
hard drive is permitted (with SSDs, it's really quick these days).

Jens

--

---
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 <mwoehlke.floss@gmail.com>
Date: Fri, 02 Oct 2015 16:55:32 -0400
Raw View
On 2015-10-02 14:22, Jens Maurer wrote:
> On 10/02/2015 07:36 PM, Matthew Woehlke wrote:
>> On 2015-09-30 20:04, David Stone wrote:
>=20
>>> "Flowing off the end of a function is equivalent to a return with no va=
lue;
>>> this results in undefined behavior in a value-returning function."
>>>
>>> This is separately called out as undefined behavior, not as part of usi=
ng
>>> an uninitialized variable.
>>
>> That could be read two ways. Given that it specifies "equivalent to a
>> return", that would imply that the compiler is required to ensure that
>> control flow at least returns properly (as I said); UB therefore arises
>> because the return value was not initialized.
>>
>> Or you could read it that the UB means the compiler is allowed to permit
>> execution to continue with whatever code happens to follow the end of
>> the function.
>=20
> Undefined behavior has no bounds, from a specification standpoint.
> So, it doesn't make sense to discuss which behavior happens when
> the standard prescribes undefined behavior.

Generally, yes, but the standard *also* said that the behavior is
"equivalent to a return with no value". Failing to return control flow
to the caller would violate that. It's an odd case where a behavior is
specified, followed by invocation of UB. Does the following UB mean that
the specified behavior may also be ignored?

> Yes, formatting your hard drive is permitted

While pedantically true, it's unlikely that an implementation would ever
do that intentionally. Most will follow the prescribed behavior (i.e.
emit instructions that will cause control to correctly return to the
caller), and the UB will be a natural consequence from the return value
being uninitialized.

The point is, my original statement wasn't intended to reflect
standardese, but a) what *actually happens* with real world compilers,
and b) the underlying *reason why* the standard makes it UB:

  - You fell off the function without initializing the return value.
  - Trying to use an unitialized value is UB.
  - Therefore, falling off a non-void function is UB.

Just because the standard doesn't spell this out doesn't invalidate the
logic. (And the standard can't simply mandate some form of
initialization... for one, because there may not be a sane way for the
compiler to guess how to initialize the value, and for two, because as
Nicol pointed out elsewhere=C2=B9, there are cases when the compiler
shouldn't anyway be emitting anything more than the equivalent of a
non-valued return implicitly. We do however need at least that much,
because for a void function, behavior *is* specified.)

That said, this is all rather beside the point. On which note, it's
interesting that the standard mentions "a return with no value"...

(=C2=B9 http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/210=
71)

--=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: Jens Maurer <Jens.Maurer@gmx.net>
Date: Fri, 02 Oct 2015 23:46:50 +0200
Raw View
On 10/02/2015 10:55 PM, Matthew Woehlke wrote:
> On 2015-10-02 14:22, Jens Maurer wrote:
>> On 10/02/2015 07:36 PM, Matthew Woehlke wrote:
>>> On 2015-09-30 20:04, David Stone wrote:
>>
>>>> "Flowing off the end of a function is equivalent to a return with no value;
>>>> this results in undefined behavior in a value-returning function."
>>>>
>>>> This is separately called out as undefined behavior, not as part of using
>>>> an uninitialized variable.
>>>
>>> That could be read two ways. Given that it specifies "equivalent to a
>>> return", that would imply that the compiler is required to ensure that
>>> control flow at least returns properly (as I said); UB therefore arises
>>> because the return value was not initialized.
>>>
>>> Or you could read it that the UB means the compiler is allowed to permit
>>> execution to continue with whatever code happens to follow the end of
>>> the function.
>>
>> Undefined behavior has no bounds, from a specification standpoint.
>> So, it doesn't make sense to discuss which behavior happens when
>> the standard prescribes undefined behavior.
>
> Generally, yes, but the standard *also* said that the behavior is
> "equivalent to a return with no value". Failing to return control flow
> to the caller would violate that. It's an odd case where a behavior is
> specified, followed by invocation of UB. Does the following UB mean that
> the specified behavior may also be ignored?

Yes, of course.  It's undefined behavior.

>> Yes, formatting your hard drive is permitted
>
> While pedantically true, it's unlikely that an implementation would ever
> do that intentionally. Most will follow the prescribed behavior (i.e.
> emit instructions that will cause control to correctly return to the
> caller), and the UB will be a natural consequence from the return value
> being uninitialized.

Well, uninitialized "unsigned char"s don't yield undefined behavior,
so that alone doesn't help.

> The point is, my original statement wasn't intended to reflect
> standardese, but a) what *actually happens* with real world compilers,

Oh, sorry, I thought this mailing list said "std-" in its name.

> and b) the underlying *reason why* the standard makes it UB:

That's not the full story.  The point is that some functions
might never flow off the end (which, in general, the compiler
cannot prove or disprove in all cases).  We could require that
all value-returning functions must end with "return <something>",
but we don't want to, because that would generate unused code
for functions that never flow off the end.

Jens

--

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

.