Topic: Apply std::common_type_t to deduce final return type


Author: anonymous.from.applecity@gmail.com
Date: Sat, 23 Jun 2018 13:14:31 -0700 (PDT)
Raw View
------=_Part_21130_1016860082.1529784871278
Content-Type: multipart/alternative;
 boundary="----=_Part_21131_251306515.1529784871279"

------=_Part_21131_251306515.1529784871279
Content-Type: text/plain; charset="UTF-8"

Problem*:*

When trying to mix std::optional with lambdas, I run into some rather
annoying issue. I need to always use trailing return type syntax to get it
deduced correctly in situations like this (e.g. when return std::nullopt
comes first):

[](auto args)
{
    if (!check(args))
        return std::nullopt;

    return foo(args); //returns some std::optional<T>
}

The above will not compile, as std::nullopt_t cannot be converted to
std::optional<T>.

Context*:*

I'm trying to implement try_in_sequence, which basically executes functions
passed as arguments one by one, until one succeeds (e.g. returns non-empty
optional). Writing return type on every one of the 4-5 lambdas per function
call is daunting. I understand that lambda's return type is consistent with
auto, but it doesn't seem to be practical in this case.

Proposal*:*

Use std::common_type<return_stm_types...> as return type. E.g. use auto on
each return statement *individually*, then deduce common type using
`std::common_type`. std::common_type<std::nullopt_t, std::optional<int>>
indeed yields std::optional<int>, as shown in shown in this example
<https://wandbox.org/permlink/oIhIR7QsmvThbSoM>:


#include <type_traits>
#include <optional>

template <typename>
struct undefined;

int main()
{
    using common_t = std::common_type_t<std::nullopt_t, std::optional<int>>;
    static_assert(std::is_same_v<std::optional<int>, common_t>);
    //undefined<std::common_type_t<std::nullopt_t, std::optional<int>>> foo;
}

Possible damage:

I cannot think of any at the moment. I never encountered a case where
compilation error inside of lambda would be of any use. I believe this
shouldn't affect existing code, as std::common_type is conversion rules
friendly (not 100% sure though).





--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/7772686a-7e80-4c28-a87b-c5dc11450cc6%40isocpp.org.

------=_Part_21131_251306515.1529784871279
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div><font size=3D"4">Problem</font><b>:</b><br></div><div=
><br></div><div>When trying to mix <code><span style=3D"color: rgb(11, 83, =
148);"><span style=3D"background-color: rgb(238, 238, 238);"><span style=3D=
"font-family: courier new, monospace;">std::optional</span></span></span> w=
ith lambdas, I run into some rather annoying issue. I need to always use tr=
ailing return type syntax to get it deduced correctly in situations like th=
is (e.g. when </code><code><code><span style=3D"color: rgb(11, 83, 148);"><=
span style=3D"background-color: rgb(238, 238, 238);"><span style=3D"font-fa=
mily: courier new, monospace;">return std::nullopt</span></span></span></co=
de> comes first):</code></div><div><code><br></code></div><div><code><div s=
tyle=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 1=
87); border-style: solid; border-width: 1px; overflow-wrap: break-word;" cl=
ass=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"subprettyprin=
t"><span style=3D"color: #660;" class=3D"styled-by-prettify">[](</span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> args</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #0=
00;" 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 =C2=A0 </span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">if</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">(!</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">check</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify">args</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">))</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">ret=
urn</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> std</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">nullopt</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><br>=C2=A0 =C2=A0 </span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">return</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> foo</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify">args</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> </span><span style=3D"color: #800;" class=3D"styled-b=
y-prettify">//returns some std::optional&lt;T&gt;</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></span></div></code></div><br>The above will no=
t compile, as <span style=3D"color: rgb(11, 83, 148);"><span style=3D"backg=
round-color: rgb(238, 238, 238);"><span style=3D"font-family: courier new, =
monospace;">std::nullopt_t</span></span></span> cannot be converted to <spa=
n style=3D"color: rgb(11, 83, 148);"><span style=3D"background-color: rgb(2=
38, 238, 238);">std::optional&lt;T&gt;</span></span>. <br></code></div><div=
><code><br></code></div><div><code><font size=3D"4">Context</font><b>:</b><=
/code></div><div><code><b><br></b></code></div><div><code>I&#39;m trying to=
 implement <span style=3D"color: rgb(11, 83, 148);"><span style=3D"backgrou=
nd-color: rgb(238, 238, 238);"><span style=3D"font-family: courier new, mon=
ospace;">try_in_sequence</span></span></span>, which basically executes fun=
ctions passed as arguments one by one, until one succeeds (e.g. returns non=
-empty optional). Writing return type on every one of the 4-5 lambdas per f=
unction call is daunting. I understand that lambda&#39;s return type is con=
sistent with <span style=3D"color: rgb(11, 83, 148);"><span style=3D"backgr=
ound-color: rgb(238, 238, 238);"><span style=3D"font-family: courier new, m=
onospace;">auto</span></span></span>, but it doesn&#39;t seem to be practic=
al in this case.</code></div><div><code><br></code></div><div><code><font s=
ize=3D"4">Proposal</font><b>:</b></code></div><div><code><b><br></b></code>=
</div><div><code>Use <span style=3D"color: rgb(11, 83, 148);"><span style=
=3D"background-color: rgb(238, 238, 238);"><span style=3D"font-family: cour=
ier new, monospace;">std::common_type&lt;return_stm_types...&gt;</span></sp=
an></span> as return type. E.g. use </code><code><code><span style=3D"color=
: rgb(11, 83, 148);"><span style=3D"background-color: rgb(238, 238, 238);">=
<span style=3D"font-family: courier new, monospace;">auto</span></span></sp=
an></code> on each return statement <i>individually</i>, then deduce common=
 type using `std::common_type`. </code><code><code><span style=3D"color: rg=
b(11, 83, 148);"><span style=3D"background-color: rgb(238, 238, 238);"><spa=
n style=3D"font-family: courier new, monospace;">std::common_type&lt;std::n=
ullopt_t, std::optional&lt;int&gt;&gt;</span></span></span></code> indeed y=
ields </code><code><code><span style=3D"color: rgb(11, 83, 148);"><span sty=
le=3D"background-color: rgb(238, 238, 238);">std::optional&lt;int&gt;</span=
></span></code>, as shown in shown in <a href=3D"https://wandbox.org/permli=
nk/oIhIR7QsmvThbSoM">this example</a>:</code></div><div><code><br></code></=
div><div style=3D"background-color: rgb(250, 250, 250); border-color: rgb(1=
87, 187, 187); border-style: solid; border-width: 1px; overflow-wrap: break=
-word;" class=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"sub=
prettyprint"><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
</span><span style=3D"color: #800;" class=3D"styled-by-prettify">#include</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #080;" class=3D"styled-by-prettify">&lt;type_traits&gt;</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><=
span style=3D"color: #800;" class=3D"styled-by-prettify">#include</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #080;" class=3D"styled-by-prettify">&lt;optional&gt;</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">template</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #080;" class=3D"styled-by-prettify">&lt;typename&gt;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">struct</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">undefined</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><br></span><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">int</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> main</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">()</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 <=
/span><span style=3D"color: #008;" class=3D"styled-by-prettify">using</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> common_t </span=
><span style=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"colo=
r: #000;" class=3D"styled-by-prettify">common_type_t</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">&lt;</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">nullopt_t</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> std</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">opt=
ional</span><span style=3D"color: #080;" class=3D"styled-by-prettify">&lt;i=
nt&gt;</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;=
;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=
=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>static_assert</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">std</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">is_same_v</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">std</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">optional</span><span style=3D"color: #080;=
" class=3D"styled-by-prettify">&lt;int&gt;</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> common_t</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&gt;);</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #800;" c=
lass=3D"styled-by-prettify">//undefined&lt;std::common_type_t&lt;std::nullo=
pt_t, std::optional&lt;int&gt;&gt;&gt; foo;</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></div></code></div><div><code><br><font =
size=3D"4">Possible damage:</font></code></div><div><code><b><br></b></code=
></div><div><code>I cannot think of any at the moment. I never encountered =
a case where compilation error inside of lambda would be of any use. I beli=
eve this shouldn&#39;t affect existing code, as </code><code><code><code><s=
pan style=3D"color: rgb(11, 83, 148);"><span style=3D"background-color: rgb=
(238, 238, 238);"><span style=3D"font-family: courier new, monospace;">std:=
:common_type</span></span></span></code></code> is conversion rules friendl=
y (not 100% sure though).<br></code></div><div><code><br></code></div><div>=
<code><br></code></div><div><code><br></code></div><div><code><br></code></=
div><br></div>

<p></p>

-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/7772686a-7e80-4c28-a87b-c5dc11450cc6%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/7772686a-7e80-4c28-a87b-c5dc11450cc6=
%40isocpp.org</a>.<br />

------=_Part_21131_251306515.1529784871279--

------=_Part_21130_1016860082.1529784871278--

.