Topic: using const to signify an expectation of a
Author: Patrice Roy <patricer@gmail.com>
Date: Sat, 27 Aug 2016 17:29:51 -0400
Raw View
--001a11425e44cd7dc2053b14549c
Content-Type: text/plain; charset=UTF-8
Would http://en.cppreference.com/w/cpp/utility/as_const satisfy you?
2016-08-27 16:52 GMT-04:00 Till Heinzel <tillheinzel@hotmail.com>:
>
> I suspect this to have been proposed in some form or other before, but I
> couldn't find anything. It is also completely from a users perspective, as
> I am not an expert on implementation details. This may also already be
> possible in some form, in which case I apologize for my ignorance.
>
> In short, I want to be able to classify a variable passed to a function as
> const, without having to define it const:
>
> void f(int){}
>
>
> int main()
> {
> int i = 0;
> f(const i); // requires the function signature of f to be such, that
> i cannot be modified by it. So passed by value or const ref.
> }
>
> In this example it is pretty unnecessary, but it could be useful in
> certain situations.
> The idea is that the interface of the called function is more explicitly
> specified by the caller, which could make it easier to find errors
> introduced by a change in the interface of a function.
>
> some cases:
> 1) The most useful situation I can think of is when calling dependent
> functions within templates:
>
> template<class T>
> void f(T& t)
> {
> X x{};
> auto y = t.g(x);
> ... do more stuff with x, y, t
> }
>
> In principle, it is unclear whether g modifies x or not. It could easily
> take a reference and change x. We would have to depend on the name of the
> function or check all possible T used with f to be certain.
> So the modified line would be:
>
> auto x = T.g(const x);
>
>
> In this case it would implicitly constrain the possible types of T. It
> would also not make x a constant, so it could still be modified in the rest
> of the function.
>
> 2) It could help specify overload resolution with forwarding references
> (note: This may be a little artificial, I have not met the problem in code).
>
> struct Z{};
>
> void f(const Z& z);
>
> template<class T> void f(T&& t){...}
>
> int main()
> {
> Z z1{};
> const Z z2{};
> f(z1); // calls template with T = Z&
> f(z2); // calls f(const Z&)
> // f(const z1) // would call f(const Z&)
> }
>
> In both cases the same could be achieved with a const& alias, but that
> would be less easy to read and might introduce runtime overhead (possibly
> extra pointers?).
> I think it could also be achieved with metaprogramming or concepts.
> Another alternative might be to use casts to const&, although that would
> definitely impede readability. I'm also not completely certain about the
> implementation of casts, but if it works like other function-calls, this
> may create extra indirection through more pointers.
>
>
> - It would not introduce any new keywords, and it would not break any
> existing code, as const can already not be used for names.
> - It might decrease readability if used excessively.
> - However, it might also catch some errors. In general, it would be a
> way to document programmer intent in code, which would be checkable by a
> compiler. The alternative of using an alias might actually be a way to
> implement this, but then there might be runtime overhead. In principle,
> this should be a compile-time feature only.
> - I have not thought too much about pointers as I try to avoid raw
> ones, but I guess a const would imply "const* const" and a mutable the
> other extreme of "*"
>
>
> Going further, a similar feature might be useful for cases where we want
> to specify a function to be expected to modify an object. This might again
> be useful in template code, where we do not know the exact interface to the
> called function. The keyword is a little less clear, but mutable might
> work, also the best would be something like out, as in c#, but that would
> introduce a new keyword. The implication would be that the function called
> must be able to modify the object, which excludes pass by value or const&.
>
> Another direction to go is to also allow the specifier on the function
> call itself:
>
> void f(T& t){
> t.const g();
> }
>
> which might again decrease readability but increase compile-time checks.
> As const-correctness is supposed to relate to the external state of an
> object, this would express, that we do not expect the behaviour of the
> object t to be changed after this call.
>
> Again something like mutable might be useful to specify when we expect a
> mutator.
>
> All in all, I see this as mostly useful in template-code, where the exact
> signature of a called function might be unknown, and to increase compile
> time checking of expected behaviour of functions.
>
> --
> 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/25f8ca3e-9d62-4fd9-
> a178-a7707425b315%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/25f8ca3e-9d62-4fd9-a178-a7707425b315%40isocpp.org?utm_medium=email&utm_source=footer>
> .
>
--
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/CAKiZDp2qZZR_dDTkV%3Dqn9BQFCN6xaoeg-m2%3Dy80d%2B8AbM1s8jw%40mail.gmail.com.
--001a11425e44cd7dc2053b14549c
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Would <a href=3D"http://en.cppreference.com/w/cpp/utility/=
as_const">http://en.cppreference.com/w/cpp/utility/as_const</a> satisfy you=
?<br></div><div class=3D"gmail_extra"><br><div class=3D"gmail_quote">2016-0=
8-27 16:52 GMT-04:00 Till Heinzel <span dir=3D"ltr"><<a href=3D"mailto:t=
illheinzel@hotmail.com" target=3D"_blank">tillheinzel@hotmail.com</a>></=
span>:<br><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><br></div><d=
iv>I suspect this to have been proposed in some form or other before, but I=
couldn't find anything. It is also completely from a users perspective=
, as I am not an expert on implementation details. This may also already be=
possible in some form, in which case I apologize for my ignorance.</div><d=
iv><br></div><div>In short, I want to be able to classify a variable passed=
to a function as const, without having to define it const:</div><div><br><=
/div><div style=3D"border:1px solid rgb(187,187,187);word-wrap:break-word;b=
ackground-color:rgb(250,250,250)"><code><div><span style=3D"color:#008">voi=
d</span><span style=3D"color:#000"> f</span><span style=3D"color:#660">(</s=
pan><span style=3D"color:#008">int</span><span style=3D"color:#660">){}</sp=
an><span style=3D"color:#000"><br><br><br></span><span style=3D"color:#008"=
>int</span><span style=3D"color:#000"> main</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 =C2=A0 </span><span style=3D=
"color:#008">int</span><span style=3D"color:#000"> i </span><span style=3D"=
color:#660">=3D</span><span style=3D"color:#000"> </span><span style=3D"col=
or:#066">0</span><span style=3D"color:#660">;</span><span style=3D"color:#0=
00"><br>=C2=A0 =C2=A0 f</span><span style=3D"color:#660">(</span><span styl=
e=3D"color:#008">const</span><span style=3D"color:#000"> i</span><span styl=
e=3D"color:#660">);</span><span style=3D"color:#000"> </span><span style=3D=
"color:#800">// requires the function signature of f to be such, that i can=
not be modified by it. So passed by value or const ref.</span><span style=
=3D"color:#000"><br></span><span style=3D"color:#660">}</span></div></code>=
</div><div><br></div><div>In this example it is pretty unnecessary, but it =
could be useful in certain situations.</div><div>The idea is that the inter=
face of the called function is more explicitly specified by the caller, whi=
ch could make it easier to find errors introduced by a change in the interf=
ace of a function.</div><div><br></div><div>some cases:</div><div>1) The mo=
st useful situation I can think of is when calling dependent functions with=
in templates:</div><div><br></div><div style=3D"border:1px solid rgb(187,18=
7,187);word-wrap:break-word;background-color:rgb(250,250,250)"><code><div><=
span style=3D"color:#008">template</span><span style=3D"color:#660"><</s=
pan><span style=3D"color:#008">class</span><span style=3D"color:#000"> T</s=
pan><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"> f</s=
pan><span style=3D"color:#660">(</span><span style=3D"color:#000">T</span><=
span style=3D"color:#660">&</span><span style=3D"color:#000"> t</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>=C2=A0 =C2=
=A0 X x</span><span style=3D"color:#660">{};</span><span style=3D"color:#00=
0"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">auto</span><span sty=
le=3D"color:#000"> y </span><span style=3D"color:#660">=3D</span><span styl=
e=3D"color:#000"> t</span><span style=3D"color:#660">.</span><span style=3D=
"color:#000">g</span><span style=3D"color:#660">(</span><span style=3D"colo=
r:#000">x</span><span style=3D"color:#660">);</span><span style=3D"color:#0=
00"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#660">...</span><span sty=
le=3D"color:#000"> </span><span style=3D"color:#008">do</span><span style=
=3D"color:#000"> more stuff </span><span style=3D"color:#008">with</span><s=
pan style=3D"color:#000"> x</span><span style=3D"color:#660">,</span><span =
style=3D"color:#000"> y</span><span style=3D"color:#660">,</span><span styl=
e=3D"color:#000"> t<br></span><span style=3D"color:#660">}</span></div></co=
de></div><div><br></div><div>In principle, it is unclear whether g modifies=
x or not. It could easily take a reference and change x. We would have to =
depend on the name of the function or check all possible T used with f to b=
e certain.</div><div>So the modified line would be:</div><div><br></div><di=
v><div style=3D"border:1px solid rgb(187,187,187);word-wrap:break-word;back=
ground-color:rgb(250,250,250)"><code><div><span style=3D"color:#008">auto</=
span><span style=3D"color:#000"> x </span><span style=3D"color:#660">=3D</s=
pan><span style=3D"color:#000"> T</span><span style=3D"color:#660">.</span>=
<span style=3D"color:#000">g</span><span style=3D"color:#660">(</span><span=
style=3D"color:#008">const</span><span style=3D"color:#000"> x</span><span=
style=3D"color:#660">);</span></div></code></div><br></div><div><br></div>=
<div>In this case it would implicitly constrain the possible types of T. It=
would also not make x a constant, so it could still be modified in the res=
t of the function.</div><div><br></div><div>2) =C2=A0It could help specify =
overload resolution with forwarding references (note: This may be a little =
artificial, I have not met the problem in code).</div><div><br></div><div>s=
truct Z{};</div><div><br></div><div>void f(const Z& z);</div><div><br><=
/div><div>template<class T> void f(T&& t){...}</div><div><br>=
</div><div>int main()</div><div>{</div><div>=C2=A0 =C2=A0 Z z1{};</div><div=
><span style=3D"white-space:pre-wrap"> </span>const Z z2{};</div><div><span=
style=3D"white-space:pre-wrap"> </span></div><div><span style=3D"white-spa=
ce:pre-wrap"> </span>f(z1); // calls template with T =3D Z&</div><div><=
span style=3D"white-space:pre-wrap"> </span>f(z2); // calls f(const Z&)=
</div><div><span style=3D"white-space:pre-wrap"> </span>// f(const z1) // w=
ould call f(const Z&)</div><div>}</div><div><br></div><div>In both case=
s the same could be achieved with a const& alias, but that would be les=
s easy to read and might introduce runtime overhead (possibly extra pointer=
s?).</div><div>I think it could also be achieved with metaprogramming or co=
ncepts.</div><div>Another alternative might be to use casts to const&, =
although that would definitely impede readability. I'm also not complet=
ely certain about the implementation of casts, but if it works like other f=
unction-calls, this may create extra indirection through more pointers.</di=
v><div><br></div><div><ul><li>It would not introduce any new keywords, and =
it would not break any existing code, as const can already not be used for =
names.=C2=A0<br></li><li>It might decrease readability if used excessively.=
=C2=A0<br></li><li>However, it might also catch some errors. In general, it=
would be a way to document programmer intent in code, which would be check=
able by a compiler. The alternative of using an alias might actually be a w=
ay to implement this, but then there might be runtime overhead. In principl=
e, this should be a compile-time feature only.<br></li><li><span style=3D"l=
ine-height:normal">I have not thought too much about pointers as I try to a=
void raw ones, but I guess a const would imply "const* const" and=
a mutable the other extreme =C2=A0of "*"</span><br></li></ul></d=
iv><div><br></div><div>Going further, a similar feature might be useful for=
cases where we want to specify a function to be expected to modify an obje=
ct. This might again be useful in template code, where we do not know the e=
xact interface to the called function. The keyword is a little less clear, =
but mutable might work, also the best would be something like out, as in c#=
, but that would introduce a new keyword. The implication would be that the=
function called must be able to modify the object, which excludes pass by =
value or const&.=C2=A0</div><div><br></div><div>Another direction to go=
is to also allow the specifier on the function call itself:</div><div><br>=
</div><div style=3D"border:1px solid rgb(187,187,187);word-wrap:break-word;=
background-color:rgb(250,250,250)"><code><div><span style=3D"color:#008">vo=
id</span><span style=3D"color:#000"> f</span><span style=3D"color:#660">(</=
span><span style=3D"color:#000">T</span><span style=3D"color:#660">&</s=
pan><span style=3D"color:#000"> t</span><span style=3D"color:#660">){</span=
><span style=3D"color:#000"><br>=C2=A0 =C2=A0 t</span><span style=3D"color:=
#660">.</span><span style=3D"color:#008">const</span><span style=3D"color:#=
000"> g</span><span style=3D"color:#660">();</span><span style=3D"color:#00=
0"><br></span><span style=3D"color:#660">}</span><span style=3D"color:#000"=
><br></span></div></code></div><div><br></div><div>which might again decrea=
se readability but increase compile-time checks. As const-correctness is su=
pposed to relate to the external state of an object, this would express, th=
at we do not expect the behaviour of the object t to be changed after this =
call.=C2=A0</div><div><br></div><div>Again something like mutable might be =
useful to specify when we expect a mutator.=C2=A0</div><div><br></div><div>=
All in all, I see this as mostly useful in template-code, where the exact s=
ignature of a called function might be unknown, and to increase compile tim=
e checking of expected behaviour of functions.</div></div><span class=3D"HO=
EnZb"><font color=3D"#888888">
<p></p>
-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@<wbr>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>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/25f8ca3e-9d62-4fd9-a178-a7707425b315%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/25f8=
ca3e-9d62-4fd9-<wbr>a178-a7707425b315%40isocpp.org</a><wbr>.<br>
</font></span></blockquote></div><br></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+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/CAKiZDp2qZZR_dDTkV%3Dqn9BQFCN6xaoeg-m=
2%3Dy80d%2B8AbM1s8jw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAKiZDp2qZZ=
R_dDTkV%3Dqn9BQFCN6xaoeg-m2%3Dy80d%2B8AbM1s8jw%40mail.gmail.com</a>.<br />
--001a11425e44cd7dc2053b14549c--
.
Author: "'Matt Calabrese' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Mon, 29 Aug 2016 11:07:16 -0700
Raw View
--001a114dd88c04a13d053b39bcd7
Content-Type: text/plain; charset=UTF-8
On Sat, Aug 27, 2016 at 2:29 PM, Patrice Roy <patricer@gmail.com> wrote:
> Would http://en.cppreference.com/w/cpp/utility/as_const satisfy you?
>
+1
This is the solution I also use and recommend for simple cases like this.
Notably, this is a single case of a more general problem that doesn't have
a simple solution yet in the language -- properly interacting with a model
of a concept in the "correct" way (in this case the concept is a Callable
that takes a parameter either by value or by reference-to-const). In the
very general case, you can get a similar effect from using a level of
indirection of something like a traits class, which behaves like a
concept_map of pre-C++11 concepts. The idea is that in the middle-man
traits class you'd have your concept's associated functions with the
*exact* signature and overload set that the concept may specify. All that
function does internally is forward along the parameter to the underlying
implementation. This way, all users of models of the concept interact with
the same top-level signature (such as one that takes a reference-to-const)
and they don't have to worry about what happens if their argument is, for
instance cv-unqualified, or an r-value instead of a l-value, etc., since
the middle-man has the proper signature and overload set. Again, though,
for basic things like callbacks, as_const is the simplest solution by far.
--
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/CANh8DEnjs%2BiVMXqjV%3D8Yr9Y8Cb%3DgD6yQr%3Df4cRZut%2BFSHWNVNA%40mail.gmail.com.
--001a114dd88c04a13d053b39bcd7
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 27, 2016 at 2:29 PM, Patrice Roy <span dir=3D"ltr"><<a href=3D"m=
ailto:patricer@gmail.com" target=3D"_blank">patricer@gmail.com</a>></spa=
n> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;b=
order-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">Would <a href=
=3D"http://en.cppreference.com/w/cpp/utility/as_const" target=3D"_blank">ht=
tp://en.cppreference.com/w/<wbr>cpp/utility/as_const</a> satisfy you?</div>=
</blockquote><div><br></div><div>+1</div><div><br></div><div>This is the so=
lution I also use and recommend for simple cases like this.</div><div><br><=
/div><div>Notably, this is a single case of a more general problem that doe=
sn't have a simple solution yet in the language -- properly interacting=
with a model of a concept in the "correct" way (in this case the=
concept is a Callable that takes a parameter either by value or by referen=
ce-to-const). In the very general case, you can get a similar effect from u=
sing a level of indirection of something like a traits class, which behaves=
like a concept_map of pre-C++11 concepts. The idea is that in the middle-m=
an traits class you'd have your concept's associated functions with=
the *exact* signature and overload set that the concept may specify. All t=
hat function does internally is forward along the parameter to the underlyi=
ng implementation. This way, all users of models of the concept interact wi=
th the same top-level signature (such as one that takes a reference-to-cons=
t) and they don't have to worry about what happens if their argument is=
, for instance cv-unqualified, or an r-value instead of a l-value, etc., si=
nce the middle-man has the proper signature and overload set. Again, though=
, for basic things like callbacks, as_const is the simplest solution by far=
..</div></div></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+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/CANh8DEnjs%2BiVMXqjV%3D8Yr9Y8Cb%3DgD6=
yQr%3Df4cRZut%2BFSHWNVNA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Df=
ooter">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CANh8DE=
njs%2BiVMXqjV%3D8Yr9Y8Cb%3DgD6yQr%3Df4cRZut%2BFSHWNVNA%40mail.gmail.com</a>=
..<br />
--001a114dd88c04a13d053b39bcd7--
.
Author: Till Heinzel <tillheinzel@hotmail.com>
Date: Tue, 30 Aug 2016 04:10:40 -0700 (PDT)
Raw View
------=_Part_5072_2107235100.1472555440353
Content-Type: multipart/alternative;
boundary="----=_Part_5073_1029626371.1472555440353"
------=_Part_5073_1029626371.1472555440353
Content-Type: text/plain; charset=UTF-8
Well, yes, as_const does what I want, except for the opposite check for a
non-const reference argument. I have no idea how that could be implemented
with templates. With a helper template maybe:
template<typename T>
struct Ref{
T& ref;
}
template<typename T>
auto make_ref(T& ref){ return Ref<t>{ref};}
template<typename T>
void f(const T& t1, Ref<T> t2ref){
T& t2 = t2ref.ref;
...
}
int main()
{
X x1{};
X x2{};
f(as_const(x1), make_ref(x2));
}
This would make it pretty clear, but make both the signature and call to f
less nice. Still, where it really matters this could work.
The trait workaround would work for more complex cases I suppose, but I
think it would result in less obvious error-messages when calling members
of a template parameter. If the supplied functions signature does not match
the expected, compilation should just fail and the error should be
something like "No member with that signature". With the traits I would
expect a less clear substitution failure, when the calling template is a
class template at least.
Anyway, I think the fundamental issue I have is that I cannot explicitly
specify the complete signature I expect of the function I am calling. If
the interface of the function is a contract, it is only fully enforcable
from one side, not both. I realize this is not a big issue, but I do think
it would make the calling code more clear.
But seeing as the goal can be achieved without new features, it would be
unnecessary.
--
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/7d03ad62-7a23-4775-a198-999a62cf20cd%40isocpp.org.
------=_Part_5073_1029626371.1472555440353
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Well, yes, as_const does what I want, except for the oppos=
ite check for a non-const reference argument. I have no idea how that could=
be implemented with templates. With a helper template maybe:<div><br></div=
><div><div class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 1=
87); word-wrap: break-word; background-color: rgb(250, 250, 250);"><code cl=
ass=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">template</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify"><</span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">typename</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> T</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">></span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br></span><font color=3D"#000088"><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">struct</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span></font><span style=3D"color: #606;" class=
=3D"styled-by-prettify">Ref</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"><br>=C2=A0 =C2=A0 T</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">&</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">ref</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><s=
pan 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-prettify">template</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">typename</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> T</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">></span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> make_ref</span><font color=3D"#666600"><span style=3D"color: =
#660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify">T</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">&</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">ref</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">return</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"c=
olor: #606;" class=3D"styled-by-prettify">Ref</span><span style=3D"color: #=
080;" class=3D"styled-by-prettify"><t></span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">{</span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">ref</span><span style=3D"color: #660;" class=3D"st=
yled-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">template</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify"><</span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>typename</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
T</span><span style=3D"color: #660;" class=3D"styled-by-prettify">></spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">void</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> f</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">const</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> T</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">&</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> t1</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #606;" class=3D"styled-by-prettify">Ref</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify"><</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">T</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">></span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> t2ref</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 T</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">&</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> t2 </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> t2ref</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">.</span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">ref</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: #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 st=
yle=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> main</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">()</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>=C2=A0 =C2=A0 X x1</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">{};</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br>=C2=A0 =C2=A0 X x2</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">{};</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br><br>=C2=A0 =C2=A0 f</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify">as_const</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify">x1</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">),</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> make_ref</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">x2</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></font></div></code></div>=
This would make it pretty clear, but make both the signature and call to f =
less nice. Still, where it really matters this could work.=C2=A0<div><div><=
br></div></div></div><div>The trait workaround would work for more complex =
cases I suppose, but I think it would result in less obvious error-messages=
when calling members of a template parameter. If the supplied functions si=
gnature does not match the expected, compilation should just fail and the e=
rror should be something like "No member with that signature". Wi=
th the traits I would expect a less clear substitution failure, when the ca=
lling template is a class template at least.=C2=A0</div><div><br></div><div=
>Anyway, I think the fundamental issue I have is that I cannot explicitly s=
pecify the complete signature I expect of the function I am calling. If the=
interface of the function is a contract, it is only fully enforcable from =
one side, not both. I realize this is not a big issue, but I do think it wo=
uld make the calling code more clear.=C2=A0</div><div>But seeing as the goa=
l can be achieved without new features, it would be unnecessary.=C2=A0</div=
></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+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/7d03ad62-7a23-4775-a198-999a62cf20cd%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/7d03ad62-7a23-4775-a198-999a62cf20cd=
%40isocpp.org</a>.<br />
------=_Part_5073_1029626371.1472555440353--
------=_Part_5072_2107235100.1472555440353--
.