Topic: Conditional const qualifier


Author: sairony@gmail.com
Date: Mon, 25 Aug 2014 03:48:35 -0700 (PDT)
Raw View
------=_Part_2517_775606090.1408963715701
Content-Type: text/plain; charset=UTF-8

Hi,

I would like to float an idea which I have been thinking on since I learned
the details of noexcept. I believe turning the const qualifier into a
compile time conditional as with noexcept ( defaulting to true ) could
finally allow us to fold a lot of code duplication for geters in
particular. Optionally support an overload for when the argument isn't
bool, in which case the constness would be deduced from whether that
argument is const or not ( would perhaps complicate matters, but would
simplify client code further ).
As stated, the greatest win as I see it would be to reduce code duplication
for geters using the following technique:

struct foo
{
// If const could deduce true / false from the constness of an argument
this would obviously get a lot less akward
auto& get_bar() const( std::is_const< typename std::remove_pointer<
decltype( this ) >::type >::value )
{
return m_Bar;
}
private:
bar m_Bar;
};

begin() / end() for iterators which decides constness from parameter could
be written as ( if constness could be deduced from parameter ):

auto begin() const( *this ) -> iterator < value_type const( *this ) >
{
//...
}


Expressions such as:

std::conditional< /*boolean expression*/, const foo, foo >::type

Instead fold to:

const( /*boolean expression*/ ) foo

enable_if shenanigans when constness is the controlling variable can
instead also use this feature ( although that's probably rather rare anyway
). Since the default behavior is compatible with previous versions of the
standard I don't think it would break compatibility.

Kind regards,
Sebastian Karlsson

--

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

<div dir=3D"ltr"><div>Hi,</div><div><br></div><div>I would like to float an=
 idea which I have been thinking on since I learned the details of noexcept=
.. I believe turning the const qualifier into a compile time conditional as =
with noexcept ( defaulting to true ) could finally allow us to fold a lot o=
f code duplication for geters in particular. Optionally support an overload=
 for when the argument isn't bool, in which case the constness would be ded=
uced from whether that argument is const or not ( would perhaps complicate =
matters, but would simplify client code further ).</div><div>As stated, the=
 greatest win as I see it would be to reduce code duplication for geters us=
ing the following technique:</div><div><br></div><div><div>struct foo</div>=
<div>{</div><div><span class=3D"Apple-tab-span" style=3D"white-space:pre"> =
</span>// If const could deduce true / false from the constness of an argum=
ent this would obviously get a lot less akward</div><div><span class=3D"App=
le-tab-span" style=3D"white-space:pre"> </span>auto&amp; get_bar() const( s=
td::is_const&lt; typename std::remove_pointer&lt; decltype( this ) &gt;::ty=
pe &gt;::value )</div><div><span class=3D"Apple-tab-span" style=3D"white-sp=
ace:pre"> </span>{</div><div><span class=3D"Apple-tab-span" style=3D"white-=
space:pre">  </span>return m_Bar;</div><div><span class=3D"Apple-tab-span" =
style=3D"white-space:pre"> </span>}</div><div>private:</div><div><span clas=
s=3D"Apple-tab-span" style=3D"white-space:pre"> </span>bar&nbsp;m_Bar;</div=
><div>};</div></div><div><br></div><div>begin() / end() for iterators which=
 decides constness from parameter could be written as ( if constness could =
be deduced from parameter ):</div><div><br></div><div><div>auto begin() con=
st( *this ) -&gt; iterator &lt; value_type const( *this ) &gt;</div><div>{<=
/div><div><span class=3D"Apple-tab-span" style=3D"white-space:pre"> </span>=
//...</div><div>}</div></div><div><br></div><div><br></div><div>Expressions=
 such as:</div><div><br></div><div><div>std::conditional&lt; /*boolean expr=
ession*/, const foo, foo &gt;::type</div></div><div><br></div><div>Instead =
fold to:</div><div><br></div><div>const( /*boolean expression*/ ) foo</div>=
<div><br></div><div>enable_if shenanigans when constness is the controlling=
 variable can instead also use this feature ( although that's probably rath=
er rare anyway ). Since the default behavior is compatible with previous ve=
rsions of the standard I don't think it would break compatibility.</div><di=
v><br></div><div>Kind regards,</div><div>Sebastian Karlsson</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_2517_775606090.1408963715701--

.


Author: Dietmar Kuehl <dietmar.kuehl@gmail.com>
Date: Mon, 25 Aug 2014 14:47:25 +0200
Raw View
> On 25 Aug 2014, at 12:48, sairony@gmail.com wrote:
> I would like to float an idea which I have been thinking on since I learn=
ed the details of noexcept. I believe turning the const qualifier into a co=
mpile time conditional as with noexcept ( defaulting to true ) could finall=
y allow us to fold a lot of code duplication for geters in particular.

I quite like the idea of const optinally becoming a compile-time conditiona=
l similar to noexcept! In the past I have discussed with people the idea of=
 "constness templates" using something like the snippet below (first in the=
 LWG at the Berlin meeting where the feedback was roughly along the lines "=
now he has lost it completely"; since then I managed to get better feedback=
, e.g., at a BSI meeting earlier this year):

    template <const cv>
    auto& foo::get_bar() cv { return this->m_bar; }

One stumbling block why I haven't pursued that direction is that somewhat r=
equires quite a bit machinary to compute the qualifiers. This need is neatl=
y avoided by making const (and, of course, volatile) conditional on a const=
ant expression. The notation using constness templates is somewhat nicer wh=
ich could lead to something like

    template <bool is_const>
    auto& foo::get_bar() const(is_const)  { return this->m_bar; }

if the argument of the const can be deduced: unlike the property of whether=
 a function throws an exception, the constness of the object pointed to by =
this is a known property of an argument. Making this property deducible doe=
sn't look like too much of a stretch.

> As stated, the greatest win as I see it would be to reduce code duplicati=
on for geters using the following technique:
>=20
> struct foo
> {
>  // If const could deduce true / false from the constness of an argument =
this would obviously get a lot less akward
>  auto& get_bar() const( std::is_const< typename std::remove_pointer< decl=
type( this ) >::type >::value )

Of course, even if the argument can't be deduced, the declaration could be =
simplified to

    auto& get_bar() const(is_const<decltype(*this)>)

Using something like:

    template <typename T>
    constexpr bool is_const =3D std::is_const<typename std::remove_referenc=
e<T>::type>::value;

Since the constness property of the object is likely to be used in multiple=
 places, I'd think it would be desirable to deduce the constness and give i=
t a name in this process. I can also imagine that compiler implementers are=
 not too keen on evaluating arbitrary expressions in the argument of const =
while determining an overload set (on the other hand, noexcept already requ=
ires this anyway).

> begin() / end() for iterators which decides constness from parameter coul=
d be written as ( if constness could be deduced from parameter ):
>=20
> auto begin() const( *this ) -> iterator < value_type const( *this ) >

When following the lead of noexept the qualifier and the expression would b=
e separate, though:

    auto begin() const(const(*this)) -> iterator<value_type const(const(*th=
is))>

Since constness of a type can already be determine without much effort, e.g=
.., using variable templates I'm not sure if the a const-testing operator is=
 really needed. This is different for the conditional const qualifier which=
 cannot be emulated for member functions.

One thing worth considering is whether the optional expression could lead t=
o ambiguities. There is no issue for the const/volatile qualifiers of membe=
r functions. When conditional const/volatile qualifiers are used for argume=
nts in a function declaration, I could image interaction with existing rule=
s.

In summary:
1. I'm definitely in favor of a mechanism making const and volatile qualifi=
ers optionally conditional on a boolean constexr.
2. A const-testing operator isn't really essential but it would probably be=
 prudent to include in an initial proposal, ideally in a disentangled way m=
aking it easy to remove it if necessary.
3. It may be reasonable to provide supporting library components.

--=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: Andrew Tomazos <andrewtomazos@gmail.com>
Date: Mon, 25 Aug 2014 15:22:18 +0200
Raw View
--089e0158c8d47fa344050174138f
Content-Type: text/plain; charset=UTF-8

This seems like an interesting idea, and I encourage you to work on it and
submit a proposal.

One thing I would observe is that perhaps you are not attacking the
surrounding issue in its full generality.

const in the suffix of a function appertains to the implicit object
parameter (this) of a member function.

Notice that:

(a) const is only one kind of specifier; and (b) the implicit object
parameter is only one kind of declared entity.

It would seem equally reasonable for any kind of on/off specifiers to be
calculated from a boolean constant expression.

For example, let b1, b2, ..., bn be a boolean constant expressions:

    constexpr_if(b1) auto x = y;

    thread_local_if(b2) auto z = w;

    struct D : virtual_if(b3) B { ... };

    void f(const_if(b4) volatile_if(b5) x);

    struct S : T
    {
         void f() override_if(b6) final_if(b7);
    }

and so on.


On Mon, Aug 25, 2014 at 12:48 PM, <sairony@gmail.com> wrote:

> Hi,
>
> I would like to float an idea which I have been thinking on since I
> learned the details of noexcept. I believe turning the const qualifier into
> a compile time conditional as with noexcept ( defaulting to true ) could
> finally allow us to fold a lot of code duplication for geters in
> particular. Optionally support an overload for when the argument isn't
> bool, in which case the constness would be deduced from whether that
> argument is const or not ( would perhaps complicate matters, but would
> simplify client code further ).
> As stated, the greatest win as I see it would be to reduce code
> duplication for geters using the following technique:
>
> struct foo
> {
> // If const could deduce true / false from the constness of an argument
> this would obviously get a lot less akward
> auto& get_bar() const( std::is_const< typename std::remove_pointer<
> decltype( this ) >::type >::value )
> {
> return m_Bar;
> }
> private:
> bar m_Bar;
> };
>
> begin() / end() for iterators which decides constness from parameter could
> be written as ( if constness could be deduced from parameter ):
>
> auto begin() const( *this ) -> iterator < value_type const( *this ) >
> {
> //...
> }
>
>
> Expressions such as:
>
> std::conditional< /*boolean expression*/, const foo, foo >::type
>
> Instead fold to:
>
> const( /*boolean expression*/ ) foo
>
> enable_if shenanigans when constness is the controlling variable can
> instead also use this feature ( although that's probably rather rare anyway
> ). Since the default behavior is compatible with previous versions of the
> standard I don't think it would break compatibility.
>
> Kind regards,
> Sebastian Karlsson
>
> --
>
> ---
> 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/.

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

<div dir=3D"ltr">This seems like an interesting idea, and I encourage you t=
o work on it and submit a proposal.<div><br></div><div>One thing I would ob=
serve is that perhaps you are not attacking the surrounding issue in its fu=
ll generality.</div>
<div><br></div><div>const in the suffix of a function appertains to the imp=
licit object parameter (this) of a member function.</div><div><br></div><di=
v>Notice that:</div><div><br></div><div>(a) const is only one kind of speci=
fier; and (b) the implicit object parameter is only one kind of declared en=
tity.</div>
<div><br></div><div>It would seem equally reasonable for any kind of on/off=
 specifiers to be calculated from a boolean constant expression.</div><div>=
<br></div><div>For example, let b1, b2, ..., bn be a boolean constant expre=
ssions:</div>
<div><br></div><div>=C2=A0 =C2=A0 constexpr_if(b1) auto x =3D y;</div><div>=
<br></div><div>=C2=A0 =C2=A0 thread_local_if(b2) auto z =3D w;</div><div><b=
r></div><div>=C2=A0 =C2=A0 struct D : virtual_if(b3) B { ... };</div><div><=
br></div><div>=C2=A0 =C2=A0 void f(const_if(b4) volatile_if(b5) x);</div>
<div><br></div><div>=C2=A0 =C2=A0 struct S : T</div><div>=C2=A0 =C2=A0 {</d=
iv><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0void f() override_if(b6) final_if=
(b7);</div><div>=C2=A0 =C2=A0 }</div><div><br></div><div>and so on.</div><d=
iv><div class=3D"gmail_extra"><br></div><div class=3D"gmail_extra">
<br><div class=3D"gmail_quote">On Mon, Aug 25, 2014 at 12:48 PM,  <span dir=
=3D"ltr">&lt;<a href=3D"mailto:sairony@gmail.com" target=3D"_blank">sairony=
@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>Hi,</div><div><br></div><div>I would like to float an=
 idea which I have been thinking on since I learned the details of noexcept=
.. I believe turning the const qualifier into a compile time conditional as =
with noexcept ( defaulting to true ) could finally allow us to fold a lot o=
f code duplication for geters in particular. Optionally support an overload=
 for when the argument isn&#39;t bool, in which case the constness would be=
 deduced from whether that argument is const or not ( would perhaps complic=
ate matters, but would simplify client code further ).</div>
<div>As stated, the greatest win as I see it would be to reduce code duplic=
ation for geters using the following technique:</div><div><br></div><div><d=
iv>struct foo</div><div>{</div><div><span style=3D"white-space:pre-wrap"> <=
/span>// If const could deduce true / false from the constness of an argume=
nt this would obviously get a lot less akward</div>
<div><span style=3D"white-space:pre-wrap"> </span>auto&amp; get_bar() const=
( std::is_const&lt; typename std::remove_pointer&lt; decltype( this ) &gt;:=
:type &gt;::value )</div><div><span style=3D"white-space:pre-wrap"> </span>=
{</div>
<div><span style=3D"white-space:pre-wrap">  </span>return m_Bar;</div><div>=
<span style=3D"white-space:pre-wrap"> </span>}</div><div>private:</div><div=
><span style=3D"white-space:pre-wrap"> </span>bar=C2=A0m_Bar;</div><div>};<=
/div></div>
<div><br></div><div>begin() / end() for iterators which decides constness f=
rom parameter could be written as ( if constness could be deduced from para=
meter ):</div><div><br></div><div><div>auto begin() const( *this ) -&gt; it=
erator &lt; value_type const( *this ) &gt;</div>
<div>{</div><div><span style=3D"white-space:pre-wrap"> </span>//...</div><d=
iv>}</div></div><div><br></div><div><br></div><div>Expressions such as:</di=
v><div><br></div><div><div>std::conditional&lt; /*boolean expression*/, con=
st foo, foo &gt;::type</div>
</div><div><br></div><div>Instead fold to:</div><div><br></div><div>const( =
/*boolean expression*/ ) foo</div><div><br></div><div>enable_if shenanigans=
 when constness is the controlling variable can instead also use this featu=
re ( although that&#39;s probably rather rare anyway ). Since the default b=
ehavior is compatible with previous versions of the standard I don&#39;t th=
ink it would break compatibility.</div>
<div><br></div><div>Kind regards,</div><div>Sebastian Karlsson</div></div><=
span class=3D"HOEnZb"><font color=3D"#888888">

<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>
</font></span></blockquote></div><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 />

--089e0158c8d47fa344050174138f--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Mon, 25 Aug 2014 07:22:03 -0700
Raw View
On Monday 25 August 2014 03:48:35 sairony@gmail.com wrote:
> auto& get_bar() const( std::is_const< typename std::remove_pointer<
> decltype( this ) >::type >::value )

This uses the fact that this points to a const object or not to determine
whether this should point to a const object or not. That's a chicken-and-the-
egg problem.

If we do this, "this" cannot appear in the expansion.

Can you give other, useful examples using this functionality without "this" ?
--
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: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Mon, 25 Aug 2014 10:06:39 -0700 (PDT)
Raw View
------=_Part_1492_1162780621.1408986399653
Content-Type: text/plain; charset=UTF-8

Another thing that could maybe use the same treatment is constexpr. This
could be useful for templates where you want certain overloads to be
constexpr.

For example the functions in my alignment proposal

template <typename T>
constexpr(std::is_integral<T>::value) T align_down(T x, size_t a)
noexcept(std::is_integral<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/.

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

<div dir=3D"ltr">Another thing that could maybe use the same treatment is c=
onstexpr. This could be useful for templates where you want certain overloa=
ds to be constexpr.<br><br>For example the functions in my alignment propos=
al<br><br>template &lt;typename T&gt;<br>constexpr(std::is_integral&lt;T&gt=
;::value) T align_down(T x, size_t a) noexcept(std::is_integral&lt;T&gt;::v=
alue);<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_1492_1162780621.1408986399653--

.


Author: Johannes Schaub <schaub.johannes@googlemail.com>
Date: Mon, 25 Aug 2014 19:13:09 +0200
Raw View
2014-08-25 15:22 GMT+02:00 Andrew Tomazos <andrewtomazos@gmail.com>:
> This seems like an interesting idea, and I encourage you to work on it and
> submit a proposal.
>
> One thing I would observe is that perhaps you are not attacking the
> surrounding issue in its full generality.
>
> const in the suffix of a function appertains to the implicit object
> parameter (this) of a member function.
>
> Notice that:
>
> (a) const is only one kind of specifier; and (b) the implicit object
> parameter is only one kind of declared entity.
>
> It would seem equally reasonable for any kind of on/off specifiers to be
> calculated from a boolean constant expression.
>
> For example, let b1, b2, ..., bn be a boolean constant expressions:
>
>     constexpr_if(b1) auto x = y;
>
>     thread_local_if(b2) auto z = w;
>
>     struct D : virtual_if(b3) B { ... };
>
>     void f(const_if(b4) volatile_if(b5) x);
>
>     struct S : T
>     {
>          void f() override_if(b6) final_if(b7);
>     }
>
> and so on.
>
>

What if we abuse static_if for this purpose. If you omit the braces,
it applies to the following qualifier

    static_if(b1)
       constexpr
    auto x = y;

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Mon, 25 Aug 2014 20:25:33 +0300
Raw View
On 25 August 2014 20:13, Johannes Schaub <schaub.johannes@googlemail.com> wrote:
> What if we abuse static_if for this purpose. If you omit the braces,
> it applies to the following qualifier
>
>     static_if(b1)
>        constexpr
>     auto x = y;


I do not expect static if to have any chance of survival outside block scopes.

--

---
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: Richard Smith <richard@metafoo.co.uk>
Date: Mon, 25 Aug 2014 10:43:45 -0700
Raw View
--001a11c2d2be7e208f050177baf7
Content-Type: text/plain; charset=UTF-8

On Mon, Aug 25, 2014 at 10:06 AM, Matthew Fioravante <fmatthew5876@gmail.com
> wrote:

> Another thing that could maybe use the same treatment is constexpr. This
> could be useful for templates where you want certain overloads to be
> constexpr.
>
> For example the functions in my alignment proposal
>
> template <typename T>
> constexpr(std::is_integral<T>::value) T align_down(T x, size_t a)
> noexcept(std::is_integral<T>::value);
>

I don't see any value in this; just mark the template as 'constexpr'. If a
particular specialization doesn't satisfy the relevant requirements, that's
fine (you simply can't use that specialization in a constant expression).

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--001a11c2d2be7e208f050177baf7
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 25, 2014 at 10:06 AM, Matthew Fioravante <span dir=3D"ltr">&lt;<a h=
ref=3D"mailto:fmatthew5876@gmail.com" target=3D"_blank">fmatthew5876@gmail.=
com</a>&gt;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr">Another thing that could ma=
ybe use the same treatment is constexpr. This could be useful for templates=
 where you want certain overloads to be constexpr.<br>
<br>For example the functions in my alignment proposal<br><br>template &lt;=
typename T&gt;<br>constexpr(std::is_integral&lt;T&gt;::value) T align_down(=
T x, size_t a) noexcept(std::is_integral&lt;T&gt;::value);</div></blockquot=
e>
<div><br></div><div>I don&#39;t see any value in this; just mark the templa=
te as &#39;constexpr&#39;. If a particular specialization doesn&#39;t satis=
fy the relevant requirements, that&#39;s fine (you simply can&#39;t use tha=
t specialization in a constant expression).</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 />

--001a11c2d2be7e208f050177baf7--

.


Author: Andrew Tomazos <andrewtomazos@gmail.com>
Date: Mon, 25 Aug 2014 19:58:20 +0200
Raw View
--001a11345f04b2eba4050177ee74
Content-Type: text/plain; charset=UTF-8

On Mon, Aug 25, 2014 at 7:13 PM, Johannes Schaub <
schaub.johannes@googlemail.com> wrote:

> 2014-08-25 15:22 GMT+02:00 Andrew Tomazos <andrewtomazos@gmail.com>:
> > This seems like an interesting idea, and I encourage you to work on it
> and
> > submit a proposal.
> >
> > One thing I would observe is that perhaps you are not attacking the
> > surrounding issue in its full generality.
> >
> > const in the suffix of a function appertains to the implicit object
> > parameter (this) of a member function.
> >
> > Notice that:
> >
> > (a) const is only one kind of specifier; and (b) the implicit object
> > parameter is only one kind of declared entity.
> >
> > It would seem equally reasonable for any kind of on/off specifiers to be
> > calculated from a boolean constant expression.
> >
> > For example, let b1, b2, ..., bn be a boolean constant expressions:
> >
> >     constexpr_if(b1) auto x = y;
> >
> >     thread_local_if(b2) auto z = w;
> >
> >     struct D : virtual_if(b3) B { ... };
> >
> >     void f(const_if(b4) volatile_if(b5) x);
> >
> >     struct S : T
> >     {
> >          void f() override_if(b6) final_if(b7);
> >     }
> >
> > and so on.
> >
> >
>
> What if we abuse static_if for this purpose. If you omit the braces,
> it applies to the following qualifier
>
>     static_if(b1)
>        constexpr
>     auto x = y;
>

I thought I just implicitly reserved static_if to mean whether or not the
static specifier is applied:

    constexpr bool b = ???;

    struct C
    {
        static_if(b) int x;
    }

if b is true, C::x has static storage duration.  If b is false it is a
non-static data member.

:)

--

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

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

<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><br><div class=3D"gmail=
_quote">On Mon, Aug 25, 2014 at 7:13 PM, Johannes Schaub <span dir=3D"ltr">=
&lt;<a href=3D"mailto:schaub.johannes@googlemail.com" target=3D"_blank">sch=
aub.johannes@googlemail.com</a>&gt;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">2014-08-25 15:22 GMT+02:00 Andrew Tomazos &l=
t;<a href=3D"mailto:andrewtomazos@gmail.com">andrewtomazos@gmail.com</a>&gt=
;:<br>

<div class=3D"">&gt; This seems like an interesting idea, and I encourage y=
ou to work on it and<br>
&gt; submit a proposal.<br>
&gt;<br>
&gt; One thing I would observe is that perhaps you are not attacking the<br=
>
&gt; surrounding issue in its full generality.<br>
&gt;<br>
&gt; const in the suffix of a function appertains to the implicit object<br=
>
&gt; parameter (this) of a member function.<br>
&gt;<br>
&gt; Notice that:<br>
&gt;<br>
&gt; (a) const is only one kind of specifier; and (b) the implicit object<b=
r>
&gt; parameter is only one kind of declared entity.<br>
&gt;<br>
&gt; It would seem equally reasonable for any kind of on/off specifiers to =
be<br>
&gt; calculated from a boolean constant expression.<br>
&gt;<br>
&gt; For example, let b1, b2, ..., bn be a boolean constant expressions:<br=
>
&gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0constexpr_if(b1) auto x =3D y;<br>
&gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0thread_local_if(b2) auto z =3D w;<br>
&gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0struct D : virtual_if(b3) B { ... };<br>
&gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0void f(const_if(b4) volatile_if(b5) x);<br>
&gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0struct S : T<br>
&gt;=C2=A0 =C2=A0 =C2=A0{<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 void f() override_if(b6) final_if(b7=
);<br>
&gt;=C2=A0 =C2=A0 =C2=A0}<br>
&gt;<br>
&gt; and so on.<br>
&gt;<br>
&gt;<br>
<br>
</div>What if we abuse static_if for this purpose. If you omit the braces,<=
br>
it applies to the following qualifier<br>
<br>
=C2=A0 =C2=A0 static_if(b1)<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0constexpr<br>
=C2=A0 =C2=A0 auto x =3D y;<br>
<div class=3D"HOEnZb"><div class=3D"h5"></div></div></blockquote></div><br>=
</div><div class=3D"gmail_extra">I thought I just implicitly reserved stati=
c_if to mean whether or not the static specifier is applied:</div><div clas=
s=3D"gmail_extra">
<br></div><div class=3D"gmail_extra">=C2=A0 =C2=A0 constexpr bool b =3D ???=
;</div><div class=3D"gmail_extra"><br></div><div class=3D"gmail_extra">=C2=
=A0 =C2=A0 struct C</div><div class=3D"gmail_extra">=C2=A0 =C2=A0 {</div><d=
iv class=3D"gmail_extra">=C2=A0 =C2=A0 =C2=A0 =C2=A0 static_if(b) int x;</d=
iv>
<div class=3D"gmail_extra">=C2=A0 =C2=A0 }</div><div class=3D"gmail_extra">=
<br></div><div class=3D"gmail_extra">if b is true, C::x has static storage =
duration. =C2=A0If b is false it is a non-static data member.</div><div cla=
ss=3D"gmail_extra">
<br></div><div class=3D"gmail_extra">:)</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 />

--001a11345f04b2eba4050177ee74--

.


Author: Richard Smith <richard@metafoo.co.uk>
Date: Mon, 25 Aug 2014 10:59:43 -0700
Raw View
--001a11c2d056a4abf0050177f381
Content-Type: text/plain; charset=UTF-8

On Mon, Aug 25, 2014 at 10:13 AM, Johannes Schaub <
schaub.johannes@googlemail.com> wrote:

> 2014-08-25 15:22 GMT+02:00 Andrew Tomazos <andrewtomazos@gmail.com>:
> > This seems like an interesting idea, and I encourage you to work on it
> and
> > submit a proposal.
> >
> > One thing I would observe is that perhaps you are not attacking the
> > surrounding issue in its full generality.
> >
> > const in the suffix of a function appertains to the implicit object
> > parameter (this) of a member function.
> >
> > Notice that:
> >
> > (a) const is only one kind of specifier; and (b) the implicit object
> > parameter is only one kind of declared entity.
> >
> > It would seem equally reasonable for any kind of on/off specifiers to be
> > calculated from a boolean constant expression.
> >
> > For example, let b1, b2, ..., bn be a boolean constant expressions:
> >
> >     constexpr_if(b1) auto x = y;
> >
> >     thread_local_if(b2) auto z = w;
> >
> >     struct D : virtual_if(b3) B { ... };
> >
> >     void f(const_if(b4) volatile_if(b5) x);
> >
> >     struct S : T
> >     {
> >          void f() override_if(b6) final_if(b7);
> >     }
> >
> > and so on.
>

I think you're trying to generalize this to a level that is not justified
by the problems being solved. constexpr_if and thread_local_if might make
sense in some limited cases (on static data members of class templates or
variable templates) but in those cases you can get the same effect through
template specialization. That might be a little awkward, but these are not
common cases.

virtual_if, override_if, and final_if seem extremely odd to me -- when a
class (template) overrides a virtual function, that is almost always an
invariant part of the design intent and it makes little sense for it to
depend on a constant expression. Again, there may be exceptions, but
without use cases I don't see a compelling argument to solve this problem.

const_if and volatile_if might have some value, but they're easily
expressed in the existing language as

  template<bool, typename T> struct const_if_impl { typedef T type; };
  template<typename T> struct const_if_impl<true, T> { typedef const T
type; };
  template<bool B, typename T> using const_if = typename const_if_impl<B,
T>::type;

.... so don't rise to the level of needing core language support.


That said, I do think that the qualifiers-on-*this problem is worth
addressing. The problem seems to me to be that we can't deduce a template
parameter from the type of *this, because we don't have an explicit *this
parameter. If we did, we could write:

  template<typename T, typename U> using apply_cv_ref = /* apply cv- and
ref-qualifiers from T to U */;

  struct S {
    template<typename T>
    apply_cv_ref<T, int &&> f(T &&star_this, int n);
  };

  int g(int &&);
  int h(int &);

  int x = g(S().f(0)); // ok, f returns int &&
  S s;
  int y = h(s.f(0)); // ok, f returns int &

As it is, we only have an "almost"-parameter tucked onto the end of the
function type. My strawman suggestion is to use a template-template
parameter to capture that parameter's type:

  struct S {
    template<template<typename> class Quals>
    Quals<int> f(int n) Quals;

    template<template<typename> class Quals>
    Quals<int> transparent_access() Quals { return
static_cast<Quals<int>>(x); }

  private:
    int x;
  };

Here, Quals will be deduced as a (built-in) alias template that applies the
cv- and ref-qualifiers of *this to its type argument.

Thoughts?

--

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

--001a11c2d056a4abf0050177f381
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 25, 2014 at 10:13 AM, Johannes Schaub <span dir=3D"ltr">&lt;<a href=
=3D"mailto:schaub.johannes@googlemail.com" target=3D"_blank">schaub.johanne=
s@googlemail.com</a>&gt;</span> wrote:<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;p=
adding-left:1ex">2014-08-25 15:22 GMT+02:00 Andrew Tomazos &lt;<a href=3D"m=
ailto:andrewtomazos@gmail.com">andrewtomazos@gmail.com</a>&gt;:<br>

<div class=3D"">&gt; This seems like an interesting idea, and I encourage y=
ou to work on it and<br>
&gt; submit a proposal.<br>
&gt;<br>
&gt; One thing I would observe is that perhaps you are not attacking the<br=
>
&gt; surrounding issue in its full generality.<br>
&gt;<br>
&gt; const in the suffix of a function appertains to the implicit object<br=
>
&gt; parameter (this) of a member function.<br>
&gt;<br>
&gt; Notice that:<br>
&gt;<br>
&gt; (a) const is only one kind of specifier; and (b) the implicit object<b=
r>
&gt; parameter is only one kind of declared entity.<br>
&gt;<br>
&gt; It would seem equally reasonable for any kind of on/off specifiers to =
be<br>
&gt; calculated from a boolean constant expression.<br>
&gt;<br>
&gt; For example, let b1, b2, ..., bn be a boolean constant expressions:<br=
>
&gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0constexpr_if(b1) auto x =3D y;<br>
&gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0thread_local_if(b2) auto z =3D w;<br>
&gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0struct D : virtual_if(b3) B { ... };<br>
&gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0void f(const_if(b4) volatile_if(b5) x);<br>
&gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0struct S : T<br>
&gt;=C2=A0 =C2=A0 =C2=A0{<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 void f() override_if(b6) final_if(b7=
);<br>
&gt;=C2=A0 =C2=A0 =C2=A0}<br>
&gt;<br>
&gt; and so on.</div></blockquote><div><br></div><div>I think you&#39;re tr=
ying to generalize this to a level that is not justified by the problems be=
ing solved. constexpr_if and thread_local_if might make sense in some limit=
ed cases (on static data members of class templates or variable templates) =
but in those cases you can get the same effect through template specializat=
ion. That might be a little awkward, but these are not common cases.</div>
<div><br></div><div>virtual_if, override_if, and final_if seem extremely od=
d to me -- when a class (template) overrides a virtual function, that is al=
most always an invariant part of the design intent and it makes little sens=
e for it to depend on a constant expression. Again, there may be exceptions=
, but without use cases I don&#39;t see a compelling argument to solve this=
 problem.</div>
<div><br></div><div>const_if and volatile_if might have some value, but the=
y&#39;re easily expressed in the existing language as</div><div><br></div><=
div>=C2=A0 template&lt;bool, typename T&gt; struct const_if_impl { typedef =
T type; };</div>
<div>=C2=A0 template&lt;typename T&gt; struct const_if_impl&lt;true, T&gt; =
{ typedef const T type; };</div><div>=C2=A0 template&lt;bool B, typename T&=
gt; using const_if =3D typename const_if_impl&lt;B, T&gt;::type;</div><div>=
<br></div>
<div>... so don&#39;t rise to the level of needing core language support.</=
div><div><br></div><div><br></div><div>That said, I do think that the quali=
fiers-on-*this problem is worth addressing. The problem seems to me to be t=
hat we can&#39;t deduce a template parameter from the type of *this, becaus=
e we don&#39;t have an explicit *this parameter. If we did, we could write:=
<br>
</div><div><br></div><div>=C2=A0 template&lt;typename T, typename U&gt; usi=
ng apply_cv_ref =3D /* apply cv- and ref-qualifiers from T to U */;</div><d=
iv><br></div><div>=C2=A0 struct S {</div><div>=C2=A0 =C2=A0 template&lt;typ=
ename T&gt;</div><div>
=C2=A0 =C2=A0 apply_cv_ref&lt;T, int &amp;&amp;&gt; f(T &amp;&amp;star_this=
, int n);</div><div>=C2=A0 };</div><div><br></div><div>=C2=A0 int g(int &am=
p;&amp;);</div><div><div>=C2=A0 int h(int &amp;);</div></div><div><br></div=
><div>=C2=A0 int x =3D g(S().f(0)); // ok, f returns int &amp;&amp;</div>
<div>=C2=A0 S s;</div><div>=C2=A0 int y =3D h(s.f(0)); // ok, f returns int=
 &amp;</div><div><br></div><div>As it is, we only have an &quot;almost&quot=
;-parameter tucked onto the end of the function type. My strawman suggestio=
n is to use a template-template parameter to capture that parameter&#39;s t=
ype:</div>
<div><br></div><div>=C2=A0 struct S {</div><div>=C2=A0 =C2=A0 template&lt;t=
emplate&lt;typename&gt; class Quals&gt;</div><div>=C2=A0 =C2=A0 Quals&lt;in=
t&gt; f(int n) Quals;</div><div><br></div><div>=C2=A0 =C2=A0 template&lt;te=
mplate&lt;typename&gt; class Quals&gt;</div>
<div>=C2=A0 =C2=A0 Quals&lt;int&gt; transparent_access() Quals { return sta=
tic_cast&lt;Quals&lt;int&gt;&gt;(x); }</div><div><br></div><div>=C2=A0 priv=
ate:</div><div>=C2=A0 =C2=A0 int x;</div><div>=C2=A0 };</div><div><br></div=
><div>Here, Quals will be deduced as a (built-in) alias template that appli=
es the cv- and ref-qualifiers of *this to its type argument.</div>
<div><br></div><div>Thoughts?</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 />

--001a11c2d056a4abf0050177f381--

.


Author: Andrew Tomazos <andrewtomazos@gmail.com>
Date: Mon, 25 Aug 2014 20:38:05 +0200
Raw View
--001a1133b54ed06eb00501787c7c
Content-Type: text/plain; charset=UTF-8

On Mon, Aug 25, 2014 at 7:59 PM, Richard Smith <richard@metafoo.co.uk>
wrote:

> On Mon, Aug 25, 2014 at 10:13 AM, Johannes Schaub <
> schaub.johannes@googlemail.com> wrote:
>
>> 2014-08-25 15:22 GMT+02:00 Andrew Tomazos <andrewtomazos@gmail.com>:
>> > This seems like an interesting idea, and I encourage you to work on it
>> and
>> > submit a proposal.
>> >
>> > One thing I would observe is that perhaps you are not attacking the
>> > surrounding issue in its full generality.
>> >
>> > const in the suffix of a function appertains to the implicit object
>> > parameter (this) of a member function.
>> >
>> > Notice that:
>> >
>> > (a) const is only one kind of specifier; and (b) the implicit object
>> > parameter is only one kind of declared entity.
>> >
>> > It would seem equally reasonable for any kind of on/off specifiers to be
>> > calculated from a boolean constant expression.
>> >
>> > For example, let b1, b2, ..., bn be a boolean constant expressions:
>> >
>> >     constexpr_if(b1) auto x = y;
>> >
>> >     thread_local_if(b2) auto z = w;
>> >
>> >     struct D : virtual_if(b3) B { ... };
>> >
>> >     void f(const_if(b4) volatile_if(b5) x);
>> >
>> >     struct S : T
>> >     {
>> >          void f() override_if(b6) final_if(b7);
>> >     }
>> >
>> > and so on.
>>
>
> I think you're trying to generalize this to a level that is not justified
> by the problems being solved. constexpr_if and thread_local_if might make
> sense in some limited cases (on static data members of class templates or
> variable templates) but in those cases you can get the same effect through
> template specialization. That might be a little awkward, but these are not
> common cases.
>
> virtual_if, override_if, and final_if seem extremely odd to me -- when a
> class (template) overrides a virtual function, that is almost always an
> invariant part of the design intent and it makes little sense for it to
> depend on a constant expression. Again, there may be exceptions, but
> without use cases I don't see a compelling argument to solve this problem.
>
> const_if and volatile_if might have some value, but they're easily
> expressed in the existing language as
>
>   template<bool, typename T> struct const_if_impl { typedef T type; };
>   template<typename T> struct const_if_impl<true, T> { typedef const T
> type; };
>   template<bool B, typename T> using const_if = typename const_if_impl<B,
> T>::type;
>
> ... so don't rise to the level of needing core language support.
>
>
> That said, I do think that the qualifiers-on-*this problem is worth
> addressing. The problem seems to me to be that we can't deduce a template
> parameter from the type of *this, because we don't have an explicit *this
> parameter. If we did, we could write:
>
>   template<typename T, typename U> using apply_cv_ref = /* apply cv- and
> ref-qualifiers from T to U */;
>
>   struct S {
>     template<typename T>
>     apply_cv_ref<T, int &&> f(T &&star_this, int n);
>   };
>
>   int g(int &&);
>   int h(int &);
>
>   int x = g(S().f(0)); // ok, f returns int &&
>   S s;
>   int y = h(s.f(0)); // ok, f returns int &
>
> As it is, we only have an "almost"-parameter tucked onto the end of the
> function type. My strawman suggestion is to use a template-template
> parameter to capture that parameter's type:
>
>   struct S {
>     template<template<typename> class Quals>
>     Quals<int> f(int n) Quals;
>
>     template<template<typename> class Quals>
>     Quals<int> transparent_access() Quals { return
> static_cast<Quals<int>>(x); }
>
>   private:
>     int x;
>   };
>
> Here, Quals will be deduced as a (built-in) alias template that applies
> the cv- and ref-qualifiers of *this to its type argument.
>
> Thoughts?
>
> Why don't we make the following two syntaxes synonymous:

    struct S { void f() const volatile &&; }

    struct S { void f(const volatile S&& this); }

that way we could do:

    struct S { template<typename T> apply_cv_ref<T, int&&> f(T&& this, int
n); }

like you want.  Or did I miss the point?

--

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

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

<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><br><div class=3D"gmail=
_quote">On Mon, Aug 25, 2014 at 7:59 PM, Richard Smith <span dir=3D"ltr">&l=
t;<a href=3D"mailto:richard@metafoo.co.uk" target=3D"_blank">richard@metafo=
o.co.uk</a>&gt;</span> wrote:<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;p=
adding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"=
gmail_quote">
<div class=3D"">On Mon, Aug 25, 2014 at 10:13 AM, Johannes Schaub <span dir=
=3D"ltr">&lt;<a href=3D"mailto:schaub.johannes@googlemail.com" target=3D"_b=
lank">schaub.johannes@googlemail.com</a>&gt;</span> wrote:<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;p=
adding-left:1ex">2014-08-25 15:22 GMT+02:00 Andrew Tomazos &lt;<a href=3D"m=
ailto:andrewtomazos@gmail.com" target=3D"_blank">andrewtomazos@gmail.com</a=
>&gt;:<br>


<div>&gt; This seems like an interesting idea, and I encourage you to work =
on it and<br>
&gt; submit a proposal.<br>
&gt;<br>
&gt; One thing I would observe is that perhaps you are not attacking the<br=
>
&gt; surrounding issue in its full generality.<br>
&gt;<br>
&gt; const in the suffix of a function appertains to the implicit object<br=
>
&gt; parameter (this) of a member function.<br>
&gt;<br>
&gt; Notice that:<br>
&gt;<br>
&gt; (a) const is only one kind of specifier; and (b) the implicit object<b=
r>
&gt; parameter is only one kind of declared entity.<br>
&gt;<br>
&gt; It would seem equally reasonable for any kind of on/off specifiers to =
be<br>
&gt; calculated from a boolean constant expression.<br>
&gt;<br>
&gt; For example, let b1, b2, ..., bn be a boolean constant expressions:<br=
>
&gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0constexpr_if(b1) auto x =3D y;<br>
&gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0thread_local_if(b2) auto z =3D w;<br>
&gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0struct D : virtual_if(b3) B { ... };<br>
&gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0void f(const_if(b4) volatile_if(b5) x);<br>
&gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0struct S : T<br>
&gt;=C2=A0 =C2=A0 =C2=A0{<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 void f() override_if(b6) final_if(b7=
);<br>
&gt;=C2=A0 =C2=A0 =C2=A0}<br>
&gt;<br>
&gt; and so on.</div></blockquote><div><br></div></div><div>I think you&#39=
;re trying to generalize this to a level that is not justified by the probl=
ems being solved. constexpr_if and thread_local_if might make sense in some=
 limited cases (on static data members of class templates or variable templ=
ates) but in those cases you can get the same effect through template speci=
alization. That might be a little awkward, but these are not common cases.<=
/div>

<div><br></div><div>virtual_if, override_if, and final_if seem extremely od=
d to me -- when a class (template) overrides a virtual function, that is al=
most always an invariant part of the design intent and it makes little sens=
e for it to depend on a constant expression. Again, there may be exceptions=
, but without use cases I don&#39;t see a compelling argument to solve this=
 problem.</div>

<div><br></div><div>const_if and volatile_if might have some value, but the=
y&#39;re easily expressed in the existing language as</div><div><br></div><=
div>=C2=A0 template&lt;bool, typename T&gt; struct const_if_impl { typedef =
T type; };</div>

<div>=C2=A0 template&lt;typename T&gt; struct const_if_impl&lt;true, T&gt; =
{ typedef const T type; };</div><div>=C2=A0 template&lt;bool B, typename T&=
gt; using const_if =3D typename const_if_impl&lt;B, T&gt;::type;</div><div>=
<br></div>

<div>... so don&#39;t rise to the level of needing core language support.</=
div><div><br></div><div><br></div><div>That said, I do think that the quali=
fiers-on-*this problem is worth addressing. The problem seems to me to be t=
hat we can&#39;t deduce a template parameter from the type of *this, becaus=
e we don&#39;t have an explicit *this parameter. If we did, we could write:=
<br>

</div><div><br></div><div>=C2=A0 template&lt;typename T, typename U&gt; usi=
ng apply_cv_ref =3D /* apply cv- and ref-qualifiers from T to U */;</div><d=
iv><br></div><div>=C2=A0 struct S {</div><div>=C2=A0 =C2=A0 template&lt;typ=
ename T&gt;</div>
<div>
=C2=A0 =C2=A0 apply_cv_ref&lt;T, int &amp;&amp;&gt; f(T &amp;&amp;star_this=
, int n);</div><div>=C2=A0 };</div><div><br></div><div>=C2=A0 int g(int &am=
p;&amp;);</div><div><div>=C2=A0 int h(int &amp;);</div></div><div><br></div=
><div>=C2=A0 int x =3D g(S().f(0)); // ok, f returns int &amp;&amp;</div>

<div>=C2=A0 S s;</div><div>=C2=A0 int y =3D h(s.f(0)); // ok, f returns int=
 &amp;</div><div><br></div><div>As it is, we only have an &quot;almost&quot=
;-parameter tucked onto the end of the function type. My strawman suggestio=
n is to use a template-template parameter to capture that parameter&#39;s t=
ype:</div>

<div><br></div><div>=C2=A0 struct S {</div><div>=C2=A0 =C2=A0 template&lt;t=
emplate&lt;typename&gt; class Quals&gt;</div><div>=C2=A0 =C2=A0 Quals&lt;in=
t&gt; f(int n) Quals;</div><div><br></div><div>=C2=A0 =C2=A0 template&lt;te=
mplate&lt;typename&gt; class Quals&gt;</div>

<div>=C2=A0 =C2=A0 Quals&lt;int&gt; transparent_access() Quals { return sta=
tic_cast&lt;Quals&lt;int&gt;&gt;(x); }</div><div><br></div><div>=C2=A0 priv=
ate:</div><div>=C2=A0 =C2=A0 int x;</div><div>=C2=A0 };</div><div><br></div=
><div>Here, Quals will be deduced as a (built-in) alias template that appli=
es the cv- and ref-qualifiers of *this to its type argument.</div>

<div><br></div><div>Thoughts?</div></div></div></div><div class=3D""><div c=
lass=3D"h5">

<p></p></div></div></blockquote></div>Why don&#39;t we make the following t=
wo syntaxes synonymous:</div><div class=3D"gmail_extra"><br></div><div clas=
s=3D"gmail_extra"><div class=3D"gmail_extra">=C2=A0 =C2=A0 struct S { void =
f() const volatile &amp;&amp;; }</div>
<div><br></div></div><div class=3D"gmail_extra">=C2=A0 =C2=A0 struct S { vo=
id f(const volatile S&amp;&amp; this); }</div><div class=3D"gmail_extra"><b=
r></div><div class=3D"gmail_extra">that way we could do:<br></div><div clas=
s=3D"gmail_extra">
<br></div><div class=3D"gmail_extra">=C2=A0 =C2=A0 struct S { template&lt;t=
ypename T&gt; apply_cv_ref&lt;T, int&amp;&amp;&gt; f(T&amp;&amp; this, int =
n); }</div><div class=3D"gmail_extra"><br></div><div class=3D"gmail_extra">=
like you want. =C2=A0Or did I miss the point?</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 />

--001a1133b54ed06eb00501787c7c--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Mon, 25 Aug 2014 11:45:05 -0700
Raw View
On Monday 25 August 2014 10:43:45 Richard Smith wrote:
> On Mon, Aug 25, 2014 at 10:06 AM, Matthew Fioravante <fmatthew5876@gmail.com
> > wrote:
> >
> > Another thing that could maybe use the same treatment is constexpr. This
> > could be useful for templates where you want certain overloads to be
> > constexpr.
> >
> > For example the functions in my alignment proposal
> >
> > template <typename T>
> > constexpr(std::is_integral<T>::value) T align_down(T x, size_t a)
> > noexcept(std::is_integral<T>::value);
>
> I don't see any value in this; just mark the template as 'constexpr'. If a
> particular specialization doesn't satisfy the relevant requirements, that's
> fine (you simply can't use that specialization in a constant expression).

The point is that the function should be allowed for that condition, the same
way that noexcept does.

--
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: sairony@gmail.com
Date: Mon, 25 Aug 2014 12:02:11 -0700 (PDT)
Raw View
------=_Part_3077_438685721.1408993331647
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Tried to send this response earlier, god knows where that ended up but=20
didn't seem to hit the mailing list, anyway, thank you for the suggestions!

>Of course, even if the argument can't be deduced, the declaration could be=
=20
simplified to
>    auto& get_bar() const(is_const<decltype(*this)>)

I would have assumed as much as well, but for some reason when I tried it=
=20
out inside a const member function with MSVC2013 it didn't seem to work.

>Using something like:
>
>    template <typename T>
>    constexpr bool is_const =3D std::is_const<typename=20
std::remove_reference<T>::type>::value;

Ah, that's definitively a better approach, and would probably make const()=
=20
as an operator redundant.

As both Dietmar & Andrew suggests it might be appropriate for more cv=20
qualifiers to sport this functionality if it's ever accepted.

> This uses the fact that this points to a const object or not to determine
> whether this should point to a const object or not. That's a=20
chicken-and-the-
> egg problem.

Doh, didn't really think about that. It would still seem well defined=20
though unless I'm missing something. When evaluating the const() member=20
function specifier the constness of this would be whatever the object of=20
the calling expression is, after const() is evaluated as member function=20
specifier we'll know if we can discard it from the set or not, and that is=
=20
whatever constness this gets when we get to the body of the function. At=20
least from a conceptual point of view I think it would work. I'm not that=
=20
familiar with the details how member functions are matched against=20
invocations however so I might very well be wrong.=20

As a consequence however leading or trailing return type could have=20
different constness of this ( and the same goes for the parameter list,=20
that is if we change it, and we're still a valid match ). But since I can't=
=20
seem to get a leading return with an expression depending on this to=20
compile I'm wondering if it might be that the standard doesn't support it. =
I=20
don't know if it's standard but both clang & GCC ( but not MSVC 2013 )=20
seems to compile expressions using this in the function signature as long=
=20
as it's an trailing return type, which I guess kind of make sense since=20
that happens after the constness of the functions has been decided. If=20
using this would be supported for both leading & trailing return type a=20
side effect of this change would probably mean that deducing the return=20
type the leading way would be using the constness of the object, while the=
=20
trailing would be whatever we changed it to. That's something which could=
=20
both probably be seen as a feature or a confusing detail.

Otherwise I'm afraid I can't think of another way to look at it for const=
=20
qualifying member functions conditionally.

Kind regards,
Sebastian Karlsson

Den m=C3=A5ndagen den 25:e augusti 2014 kl. 20:45:19 UTC+2 skrev Thiago Mac=
ieira:
>
> On Monday 25 August 2014 10:43:45 Richard Smith wrote:=20
> > On Mon, Aug 25, 2014 at 10:06 AM, Matthew Fioravante <
> fmatth...@gmail.com <javascript:>=20
> > > wrote:=20
> > >=20
> > > Another thing that could maybe use the same treatment is constexpr.=
=20
> This=20
> > > could be useful for templates where you want certain overloads to be=
=20
> > > constexpr.=20
> > >=20
> > > For example the functions in my alignment proposal=20
> > >=20
> > > template <typename T>=20
> > > constexpr(std::is_integral<T>::value) T align_down(T x, size_t a)=20
> > > noexcept(std::is_integral<T>::value);=20
> >=20
> > I don't see any value in this; just mark the template as 'constexpr'. I=
f=20
> a=20
> > particular specialization doesn't satisfy the relevant requirements,=20
> that's=20
> > fine (you simply can't use that specialization in a constant=20
> expression).=20
>
> The point is that the function should be allowed for that condition, the=
=20
> same=20
> way that noexcept does.=20
>
> --=20
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org=20
>    Software Architect - Intel Open Source Technology Center=20
>       PGP/GPG: 0x6EF45358; fingerprint:=20
>       E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358=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 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_3077_438685721.1408993331647
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Tried to send this response earlier, god knows where =
that ended up but didn't seem to hit the mailing list, anyway,&nbsp;<span s=
tyle=3D"font-family: arial, sans-serif;">thank you for the suggestions!</sp=
an></div><div><div style=3D"font-family: arial, sans-serif;"><div class=3D"=
im" style=3D"color: rgb(80, 0, 80);"><br><div>&gt;Of course, even if the ar=
gument can't be deduced, the declaration could be simplified to</div>&gt; &=
nbsp; &nbsp;auto&amp; get_bar() const(is_const&lt;decltype(*this)<wbr>&gt;)=
<div><br></div></div><div>I would have assumed as much as well, but for som=
e reason when I tried it out inside a const member function with MSVC2013 i=
t didn't seem to work.</div><div class=3D"im" style=3D"color: rgb(80, 0, 80=
);"><div><br></div><div>&gt;Using something like:<br>&gt;<br>&gt; &nbsp; &n=
bsp;template &lt;typename T&gt;<br>&gt; &nbsp; &nbsp;constexpr bool is_cons=
t =3D std::is_const&lt;typename std::remove_reference&lt;T&gt;::type<wbr>&g=
t;::value;<br></div><div><br></div></div><div>Ah, that's definitively a bet=
ter approach, and would probably make const() as an operator redundant.</di=
v><div><br></div><div>As both Dietmar &amp; Andrew suggests it might be app=
ropriate for more cv qualifiers to sport this functionality if it's ever ac=
cepted.</div><div class=3D"im" style=3D"color: rgb(80, 0, 80);"><div><br></=
div><div>&gt; This uses the fact that this points to a const object or not =
to determine<br>&gt; whether this should point to a const object or not. Th=
at's a chicken-and-the-<br>&gt; egg problem.<br></div><div><br></div></div>=
<div>Doh, didn't really think about that.&nbsp;It would still seem well def=
ined though unless I'm missing something. When evaluating the const() membe=
r function specifier the constness of this would be whatever the object of =
the calling expression is, after const() is evaluated as member function sp=
ecifier we'll know if we can discard it from the set or not, and that is wh=
atever constness this gets when we get to the body of the function. At leas=
t from a conceptual point of view I think it would work. I'm not that famil=
iar with the details how member functions are matched against invocations h=
owever so I might very well be wrong.&nbsp;</div><div><br></div><div><font =
face=3D"arial, sans-serif">As a consequence however leading or trailing ret=
urn type could have different constness of this ( and the same goes for the=
 parameter list, that is if we change it, and we're still a valid match ). =
But since I can't seem to get a leading return with an expression depending=
 on this to compile I'm wondering if it might be that the standard doesn't =
support it.&nbsp;</font>I don't know if it's standard but both clang &amp; =
GCC ( but not MSVC 2013 ) seems to compile expressions using this in the fu=
nction signature as long as it's an trailing return type, which I guess kin=
d of make sense since that happens after the constness of the functions has=
 been decided. If using this would be supported for both leading &amp; trai=
ling return type a side effect of this change would probably mean that dedu=
cing the return type the leading way would be using the constness of the ob=
ject, while the trailing would be whatever we changed it to. That's somethi=
ng which could both probably be seen as a feature or a confusing detail.</d=
iv><div><br></div><div><font face=3D"arial, sans-serif">Otherwise I'm afrai=
d I can't think of another way to look at it for const qualifying member fu=
nctions conditionally.</font></div><div><br></div></div><div style=3D"font-=
family: arial, sans-serif;">Kind regards,</div><div style=3D"font-family: a=
rial, sans-serif;">Sebastian Karlsson</div></div><div><br></div>Den m=C3=A5=
ndagen den 25:e augusti 2014 kl. 20:45:19 UTC+2 skrev Thiago Macieira:<bloc=
kquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-l=
eft: 1px #ccc solid;padding-left: 1ex;">On Monday 25 August 2014 10:43:45 R=
ichard Smith wrote:
<br>&gt; On Mon, Aug 25, 2014 at 10:06 AM, Matthew Fioravante &lt;<a href=
=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"BpWebHvNxmIJ" o=
nmousedown=3D"this.href=3D'javascript:';return true;" onclick=3D"this.href=
=3D'javascript:';return true;">fmatth...@gmail.com</a>
<br>&gt; &gt; wrote:
<br>&gt; &gt;=20
<br>&gt; &gt; Another thing that could maybe use the same treatment is cons=
texpr. This
<br>&gt; &gt; could be useful for templates where you want certain overload=
s to be
<br>&gt; &gt; constexpr.
<br>&gt; &gt;=20
<br>&gt; &gt; For example the functions in my alignment proposal
<br>&gt; &gt;=20
<br>&gt; &gt; template &lt;typename T&gt;
<br>&gt; &gt; constexpr(std::is_integral&lt;T&gt;:<wbr>:value) T align_down=
(T x, size_t a)
<br>&gt; &gt; noexcept(std::is_integral&lt;T&gt;::<wbr>value);
<br>&gt;=20
<br>&gt; I don't see any value in this; just mark the template as 'constexp=
r'. If a
<br>&gt; particular specialization doesn't satisfy the relevant requirement=
s, that's
<br>&gt; fine (you simply can't use that specialization in a constant expre=
ssion).
<br>
<br>The point is that the function should be allowed for that condition, th=
e same=20
<br>way that noexcept does.
<br>
<br>--=20
<br>Thiago Macieira - thiago (AT) <a href=3D"http://macieira.info" target=
=3D"_blank" onmousedown=3D"this.href=3D'http://www.google.com/url?q\75http%=
3A%2F%2Fmacieira.info\46sa\75D\46sntz\0751\46usg\75AFQjCNEswDUBNCNanbu7euhq=
Ln_62FW8ag';return true;" onclick=3D"this.href=3D'http://www.google.com/url=
?q\75http%3A%2F%2Fmacieira.info\46sa\75D\46sntz\0751\46usg\75AFQjCNEswDUBNC=
Nanbu7euhqLn_62FW8ag';return true;">macieira.info</a> - thiago (AT) <a href=
=3D"http://kde.org" target=3D"_blank" onmousedown=3D"this.href=3D'http://ww=
w.google.com/url?q\75http%3A%2F%2Fkde.org\46sa\75D\46sntz\0751\46usg\75AFQj=
CNHGRJdo5_JYG1DowztwAHAKs80XSA';return true;" onclick=3D"this.href=3D'http:=
//www.google.com/url?q\75http%3A%2F%2Fkde.org\46sa\75D\46sntz\0751\46usg\75=
AFQjCNHGRJdo5_JYG1DowztwAHAKs80XSA';return true;">kde.org</a>
<br>&nbsp; &nbsp;Software Architect - Intel Open Source Technology Center
<br>&nbsp; &nbsp; &nbsp; PGP/GPG: 0x6EF45358; fingerprint:
<br>&nbsp; &nbsp; &nbsp; E067 918B B660 DBD1 105C &nbsp;966C 33F5 F005 6EF4=
 5358
<br>
<br></blockquote><div>&nbsp;</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_3077_438685721.1408993331647--

.


Author: Richard Smith <richard@metafoo.co.uk>
Date: Mon, 25 Aug 2014 12:48:40 -0700
Raw View
--20cf307c9fca3ccac50501797903
Content-Type: text/plain; charset=UTF-8

On Mon, Aug 25, 2014 at 11:45 AM, Thiago Macieira <thiago@macieira.org>
wrote:

> On Monday 25 August 2014 10:43:45 Richard Smith wrote:
> > On Mon, Aug 25, 2014 at 10:06 AM, Matthew Fioravante <
> fmatthew5876@gmail.com
> > > wrote:
> > >
> > > Another thing that could maybe use the same treatment is constexpr.
> This
> > > could be useful for templates where you want certain overloads to be
> > > constexpr.
> > >
> > > For example the functions in my alignment proposal
> > >
> > > template <typename T>
> > > constexpr(std::is_integral<T>::value) T align_down(T x, size_t a)
> > > noexcept(std::is_integral<T>::value);
> >
> > I don't see any value in this; just mark the template as 'constexpr'. If
> a
> > particular specialization doesn't satisfy the relevant requirements,
> that's
> > fine (you simply can't use that specialization in a constant expression).
>
> The point is that the function should be allowed for that condition, the
> same
> way that noexcept does.


That's what you get today if you use 'constexpr'. What am I missing?

--

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

--20cf307c9fca3ccac50501797903
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 25, 2014 at 11:45 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:1p=
x #ccc solid;padding-left:1ex"><div class=3D"HOEnZb"><div class=3D"h5">On M=
onday 25 August 2014 10:43:45 Richard Smith wrote:<br>
&gt; On Mon, Aug 25, 2014 at 10:06 AM, Matthew Fioravante &lt;<a href=3D"ma=
ilto:fmatthew5876@gmail.com">fmatthew5876@gmail.com</a><br>
&gt; &gt; wrote:<br>
&gt; &gt;<br>
&gt; &gt; Another thing that could maybe use the same treatment is constexp=
r. This<br>
&gt; &gt; could be useful for templates where you want certain overloads to=
 be<br>
&gt; &gt; constexpr.<br>
&gt; &gt;<br>
&gt; &gt; For example the functions in my alignment proposal<br>
&gt; &gt;<br>
&gt; &gt; template &lt;typename T&gt;<br>
&gt; &gt; constexpr(std::is_integral&lt;T&gt;::value) T align_down(T x, siz=
e_t a)<br>
&gt; &gt; noexcept(std::is_integral&lt;T&gt;::value);<br>
&gt;<br>
&gt; I don&#39;t see any value in this; just mark the template as &#39;cons=
texpr&#39;. If a<br>
&gt; particular specialization doesn&#39;t satisfy the relevant requirement=
s, that&#39;s<br>
&gt; fine (you simply can&#39;t use that specialization in a constant expre=
ssion).<br>
<br>
</div></div>The point is that the function should be allowed for that condi=
tion, the same<br>
way that noexcept does.</blockquote><div><br></div><div>That&#39;s what you=
 get today if you use &#39;constexpr&#39;. What am I missing?=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 />

--20cf307c9fca3ccac50501797903--

.


Author: Richard Smith <richard@metafoo.co.uk>
Date: Mon, 25 Aug 2014 12:51:08 -0700
Raw View
--047d7b34354c14b26c0501798279
Content-Type: text/plain; charset=UTF-8

On Mon, Aug 25, 2014 at 11:38 AM, Andrew Tomazos <andrewtomazos@gmail.com>
wrote:

> On Mon, Aug 25, 2014 at 7:59 PM, Richard Smith <richard@metafoo.co.uk>
> wrote:
>
>> On Mon, Aug 25, 2014 at 10:13 AM, Johannes Schaub <
>> schaub.johannes@googlemail.com> wrote:
>>
>>> 2014-08-25 15:22 GMT+02:00 Andrew Tomazos <andrewtomazos@gmail.com>:
>>> > This seems like an interesting idea, and I encourage you to work on it
>>> and
>>> > submit a proposal.
>>> >
>>> > One thing I would observe is that perhaps you are not attacking the
>>> > surrounding issue in its full generality.
>>> >
>>> > const in the suffix of a function appertains to the implicit object
>>> > parameter (this) of a member function.
>>> >
>>> > Notice that:
>>> >
>>> > (a) const is only one kind of specifier; and (b) the implicit object
>>> > parameter is only one kind of declared entity.
>>> >
>>> > It would seem equally reasonable for any kind of on/off specifiers to
>>> be
>>> > calculated from a boolean constant expression.
>>> >
>>> > For example, let b1, b2, ..., bn be a boolean constant expressions:
>>> >
>>> >     constexpr_if(b1) auto x = y;
>>> >
>>> >     thread_local_if(b2) auto z = w;
>>> >
>>> >     struct D : virtual_if(b3) B { ... };
>>> >
>>> >     void f(const_if(b4) volatile_if(b5) x);
>>> >
>>> >     struct S : T
>>> >     {
>>> >          void f() override_if(b6) final_if(b7);
>>> >     }
>>> >
>>> > and so on.
>>>
>>
>> I think you're trying to generalize this to a level that is not justified
>> by the problems being solved. constexpr_if and thread_local_if might make
>> sense in some limited cases (on static data members of class templates or
>> variable templates) but in those cases you can get the same effect through
>> template specialization. That might be a little awkward, but these are not
>> common cases.
>>
>> virtual_if, override_if, and final_if seem extremely odd to me -- when a
>> class (template) overrides a virtual function, that is almost always an
>> invariant part of the design intent and it makes little sense for it to
>> depend on a constant expression. Again, there may be exceptions, but
>> without use cases I don't see a compelling argument to solve this problem.
>>
>> const_if and volatile_if might have some value, but they're easily
>> expressed in the existing language as
>>
>>   template<bool, typename T> struct const_if_impl { typedef T type; };
>>   template<typename T> struct const_if_impl<true, T> { typedef const T
>> type; };
>>   template<bool B, typename T> using const_if = typename const_if_impl<B,
>> T>::type;
>>
>> ... so don't rise to the level of needing core language support.
>>
>>
>> That said, I do think that the qualifiers-on-*this problem is worth
>> addressing. The problem seems to me to be that we can't deduce a template
>> parameter from the type of *this, because we don't have an explicit *this
>> parameter. If we did, we could write:
>>
>>   template<typename T, typename U> using apply_cv_ref = /* apply cv- and
>> ref-qualifiers from T to U */;
>>
>>   struct S {
>>     template<typename T>
>>      apply_cv_ref<T, int &&> f(T &&star_this, int n);
>>   };
>>
>>   int g(int &&);
>>   int h(int &);
>>
>>   int x = g(S().f(0)); // ok, f returns int &&
>>   S s;
>>   int y = h(s.f(0)); // ok, f returns int &
>>
>> As it is, we only have an "almost"-parameter tucked onto the end of the
>> function type. My strawman suggestion is to use a template-template
>> parameter to capture that parameter's type:
>>
>>   struct S {
>>     template<template<typename> class Quals>
>>     Quals<int> f(int n) Quals;
>>
>>     template<template<typename> class Quals>
>>     Quals<int> transparent_access() Quals { return
>> static_cast<Quals<int>>(x); }
>>
>>   private:
>>     int x;
>>   };
>>
>> Here, Quals will be deduced as a (built-in) alias template that applies
>> the cv- and ref-qualifiers of *this to its type argument.
>>
>> Thoughts?
>>
>> Why don't we make the following two syntaxes synonymous:
>
>     struct S { void f() const volatile &&; }
>
>     struct S { void f(const volatile S&& this); }
>
> that way we could do:
>
>     struct S { template<typename T> apply_cv_ref<T, int&&> f(T&& this, int
> n); }
>
> like you want.  Or did I miss the point?
>

I don't actually want that =) I was merely observing why the *this
qualifiers are a special case. I also think the result you get here is
harder to use than my strawman proposal.

Also, wouldn't your approach make 'this' be a reference rather than a
pointer? =)

--

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

--047d7b34354c14b26c0501798279
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 25, 2014 at 11:38 AM, Andrew Tomazos <span dir=3D"ltr">&lt;<a href=
=3D"mailto:andrewtomazos@gmail.com" target=3D"_blank">andrewtomazos@gmail.c=
om</a>&gt;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra">=
<div><div class=3D"h5"><div class=3D"gmail_quote">On Mon, Aug 25, 2014 at 7=
:59 PM, Richard Smith <span dir=3D"ltr">&lt;<a href=3D"mailto:richard@metaf=
oo.co.uk" target=3D"_blank">richard@metafoo.co.uk</a>&gt;</span> wrote:<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;p=
adding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"=
gmail_quote">

<div>On Mon, Aug 25, 2014 at 10:13 AM, Johannes Schaub <span dir=3D"ltr">&l=
t;<a href=3D"mailto:schaub.johannes@googlemail.com" target=3D"_blank">schau=
b.johannes@googlemail.com</a>&gt;</span> wrote:<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;p=
adding-left:1ex">2014-08-25 15:22 GMT+02:00 Andrew Tomazos &lt;<a href=3D"m=
ailto:andrewtomazos@gmail.com" target=3D"_blank">andrewtomazos@gmail.com</a=
>&gt;:<br>



<div>&gt; This seems like an interesting idea, and I encourage you to work =
on it and<br>
&gt; submit a proposal.<br>
&gt;<br>
&gt; One thing I would observe is that perhaps you are not attacking the<br=
>
&gt; surrounding issue in its full generality.<br>
&gt;<br>
&gt; const in the suffix of a function appertains to the implicit object<br=
>
&gt; parameter (this) of a member function.<br>
&gt;<br>
&gt; Notice that:<br>
&gt;<br>
&gt; (a) const is only one kind of specifier; and (b) the implicit object<b=
r>
&gt; parameter is only one kind of declared entity.<br>
&gt;<br>
&gt; It would seem equally reasonable for any kind of on/off specifiers to =
be<br>
&gt; calculated from a boolean constant expression.<br>
&gt;<br>
&gt; For example, let b1, b2, ..., bn be a boolean constant expressions:<br=
>
&gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0constexpr_if(b1) auto x =3D y;<br>
&gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0thread_local_if(b2) auto z =3D w;<br>
&gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0struct D : virtual_if(b3) B { ... };<br>
&gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0void f(const_if(b4) volatile_if(b5) x);<br>
&gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0struct S : T<br>
&gt;=C2=A0 =C2=A0 =C2=A0{<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 void f() override_if(b6) final_if(b7=
);<br>
&gt;=C2=A0 =C2=A0 =C2=A0}<br>
&gt;<br>
&gt; and so on.</div></blockquote><div><br></div></div><div>I think you&#39=
;re trying to generalize this to a level that is not justified by the probl=
ems being solved. constexpr_if and thread_local_if might make sense in some=
 limited cases (on static data members of class templates or variable templ=
ates) but in those cases you can get the same effect through template speci=
alization. That might be a little awkward, but these are not common cases.<=
/div>


<div><br></div><div>virtual_if, override_if, and final_if seem extremely od=
d to me -- when a class (template) overrides a virtual function, that is al=
most always an invariant part of the design intent and it makes little sens=
e for it to depend on a constant expression. Again, there may be exceptions=
, but without use cases I don&#39;t see a compelling argument to solve this=
 problem.</div>


<div><br></div><div>const_if and volatile_if might have some value, but the=
y&#39;re easily expressed in the existing language as</div><div><br></div><=
div>=C2=A0 template&lt;bool, typename T&gt; struct const_if_impl { typedef =
T type; };</div>


<div>=C2=A0 template&lt;typename T&gt; struct const_if_impl&lt;true, T&gt; =
{ typedef const T type; };</div><div>=C2=A0 template&lt;bool B, typename T&=
gt; using const_if =3D typename const_if_impl&lt;B, T&gt;::type;</div><div>=
<br></div>


<div>... so don&#39;t rise to the level of needing core language support.</=
div><div><br></div><div><br></div><div>That said, I do think that the quali=
fiers-on-*this problem is worth addressing. The problem seems to me to be t=
hat we can&#39;t deduce a template parameter from the type of *this, becaus=
e we don&#39;t have an explicit *this parameter. If we did, we could write:=
<br>


</div><div><br></div><div>=C2=A0 template&lt;typename T, typename U&gt; usi=
ng apply_cv_ref =3D /* apply cv- and ref-qualifiers from T to U */;</div><d=
iv><br></div><div>=C2=A0 struct S {</div><div>=C2=A0 =C2=A0 template&lt;typ=
ename T&gt;</div>

<div>
=C2=A0 =C2=A0 apply_cv_ref&lt;T, int &amp;&amp;&gt; f(T &amp;&amp;star_this=
, int n);</div><div>=C2=A0 };</div><div><br></div><div>=C2=A0 int g(int &am=
p;&amp;);</div><div><div>=C2=A0 int h(int &amp;);</div></div><div><br></div=
><div>=C2=A0 int x =3D g(S().f(0)); // ok, f returns int &amp;&amp;</div>


<div>=C2=A0 S s;</div><div>=C2=A0 int y =3D h(s.f(0)); // ok, f returns int=
 &amp;</div><div><br></div><div>As it is, we only have an &quot;almost&quot=
;-parameter tucked onto the end of the function type. My strawman suggestio=
n is to use a template-template parameter to capture that parameter&#39;s t=
ype:</div>


<div><br></div><div>=C2=A0 struct S {</div><div>=C2=A0 =C2=A0 template&lt;t=
emplate&lt;typename&gt; class Quals&gt;</div><div>=C2=A0 =C2=A0 Quals&lt;in=
t&gt; f(int n) Quals;</div><div><br></div><div>=C2=A0 =C2=A0 template&lt;te=
mplate&lt;typename&gt; class Quals&gt;</div>


<div>=C2=A0 =C2=A0 Quals&lt;int&gt; transparent_access() Quals { return sta=
tic_cast&lt;Quals&lt;int&gt;&gt;(x); }</div><div><br></div><div>=C2=A0 priv=
ate:</div><div>=C2=A0 =C2=A0 int x;</div><div>=C2=A0 };</div><div><br></div=
><div>Here, Quals will be deduced as a (built-in) alias template that appli=
es the cv- and ref-qualifiers of *this to its type argument.</div>


<div><br></div><div>Thoughts?</div></div></div></div><div><div>

<p></p></div></div></blockquote></div></div></div>Why don&#39;t we make the=
 following two syntaxes synonymous:</div><div class=3D"gmail_extra"><br></d=
iv><div class=3D"gmail_extra"><div class=3D"gmail_extra">=C2=A0 =C2=A0 stru=
ct S { void f() const volatile &amp;&amp;; }</div>

<div><br></div></div><div class=3D"gmail_extra">=C2=A0 =C2=A0 struct S { vo=
id f(const volatile S&amp;&amp; this); }</div><div class=3D"gmail_extra"><b=
r></div><div class=3D"gmail_extra">that way we could do:<br></div><div clas=
s=3D"gmail_extra">

<br></div><div class=3D"gmail_extra">=C2=A0 =C2=A0 struct S { template&lt;t=
ypename T&gt; apply_cv_ref&lt;T, int&amp;&amp;&gt; f(T&amp;&amp; this, int =
n); }</div><div class=3D"gmail_extra"><br></div><div class=3D"gmail_extra">=
like you want. =C2=A0Or did I miss the point?</div>
</div></blockquote><div><br></div><div>I don&#39;t actually want that =3D) =
I was merely observing why the *this qualifiers are a special case. I also =
think the result you get here is harder to use than my strawman proposal.</=
div>
<div><br></div><div>Also, wouldn&#39;t your approach make &#39;this&#39; be=
 a reference rather than a pointer? =3D)</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 />

--047d7b34354c14b26c0501798279--

.


Author: Richard Smith <richard@metafoo.co.uk>
Date: Mon, 25 Aug 2014 12:53:30 -0700
Raw View
--001a11335fa48439650501798ade
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Mon, Aug 25, 2014 at 12:02 PM, <sairony@gmail.com> wrote:

> As a consequence however leading or trailing return type could have
> different constness of this ( and the same goes for the parameter list,
> that is if we change it, and we're still a valid match ). But since I can=
't
> seem to get a leading return with an expression depending on this to
> compile I'm wondering if it might be that the standard doesn't support it=
..
>

The standard doesn't allow you to use 'this' lexically before the
cv-qualifiers in the function type, since that's the point at which its
type becomes known.

[expr.prim.general]p3:

"If a declaration declares a member function or member function template of
a class X, the expression this
is a prvalue of type =E2=80=9Cpointer to cv-qualifier-seq X=E2=80=9D betwee=
n the optional
cv-qualifer-seq and the end of the
function-definition, member-declarator, or declarator. It shall not appear
before the optional cv-qualifier-seq
and it shall not appear within the declaration of a static member function
(although its type and value
category are defined within a static member function as they are within a
non-static member function)."

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

--001a11335fa48439650501798ade
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 25, 2014 at 12:02 PM,  <span dir=3D"ltr">&lt;<a href=3D"mailto:sair=
ony@gmail.com" target=3D"_blank">sairony@gmail.com</a>&gt;</span> wrote:<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">
<div dir=3D"ltr"><div><font face=3D"arial, sans-serif" style=3D"font-family=
:arial,sans-serif">As a consequence however leading or trailing return type=
 could have different constness of this ( and the same goes for the paramet=
er list, that is if we change it, and we&#39;re still a valid match ). But =
since I can&#39;t seem to get a leading return with an expression depending=
 on this to compile I&#39;m wondering if it might be that the standard does=
n&#39;t support it.</font></div>
</div></blockquote><div><br></div><div>The standard doesn&#39;t allow you t=
o use &#39;this&#39; lexically before the cv-qualifiers in the function typ=
e, since that&#39;s the point at which its type becomes known.</div><div>
<br></div><div>[expr.prim.general]p3:</div><div><br></div><div><div>&quot;I=
f a declaration declares a member function or member function template of a=
 class X, the expression this</div><div>is a prvalue of type =E2=80=9Cpoint=
er to cv-qualifier-seq X=E2=80=9D between the optional cv-qualifer-seq and =
the end of the</div>
<div>function-definition, member-declarator, or declarator. It shall not ap=
pear before the optional cv-qualifier-seq</div><div>and it shall not appear=
 within the declaration of a static member function (although its type and =
value</div>
<div>category are defined within a static member function as they are withi=
n a non-static member function).&quot;</div></div><div><br></div></div></di=
v></div>

<p></p>

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

--001a11335fa48439650501798ade--

.


Author: Johannes Schaub <schaub.johannes@googlemail.com>
Date: Mon, 25 Aug 2014 22:15:50 +0200
Raw View
2014-08-25 19:59 GMT+02:00 Richard Smith <richard@metafoo.co.uk>:
> On Mon, Aug 25, 2014 at 10:13 AM, Johannes Schaub
> <schaub.johannes@googlemail.com> wrote:
>>
>> 2014-08-25 15:22 GMT+02:00 Andrew Tomazos <andrewtomazos@gmail.com>:
>> > This seems like an interesting idea, and I encourage you to work on it
>> > and
>> > submit a proposal.
>> >
>> > One thing I would observe is that perhaps you are not attacking the
>> > surrounding issue in its full generality.
>> >
>> > const in the suffix of a function appertains to the implicit object
>> > parameter (this) of a member function.
>> >
>> > Notice that:
>> >
>> > (a) const is only one kind of specifier; and (b) the implicit object
>> > parameter is only one kind of declared entity.
>> >
>> > It would seem equally reasonable for any kind of on/off specifiers to be
>> > calculated from a boolean constant expression.
>> >
>> > For example, let b1, b2, ..., bn be a boolean constant expressions:
>> >
>> >     constexpr_if(b1) auto x = y;
>> >
>> >     thread_local_if(b2) auto z = w;
>> >
>> >     struct D : virtual_if(b3) B { ... };
>> >
>> >     void f(const_if(b4) volatile_if(b5) x);
>> >
>> >     struct S : T
>> >     {
>> >          void f() override_if(b6) final_if(b7);
>> >     }
>> >
>> > and so on.
>
>
> I think you're trying to generalize this to a level that is not justified by
> the problems being solved. constexpr_if and thread_local_if might make sense
> in some limited cases (on static data members of class templates or variable
> templates) but in those cases you can get the same effect through template
> specialization. That might be a little awkward, but these are not common
> cases.
>
> virtual_if, override_if, and final_if seem extremely odd to me -- when a
> class (template) overrides a virtual function, that is almost always an
> invariant part of the design intent and it makes little sense for it to
> depend on a constant expression. Again, there may be exceptions, but without
> use cases I don't see a compelling argument to solve this problem.
>
> const_if and volatile_if might have some value, but they're easily expressed
> in the existing language as
>
>   template<bool, typename T> struct const_if_impl { typedef T type; };
>   template<typename T> struct const_if_impl<true, T> { typedef const T type;
> };
>   template<bool B, typename T> using const_if = typename const_if_impl<B,
> T>::type;
>
> ... so don't rise to the level of needing core language support.
>
>
> That said, I do think that the qualifiers-on-*this problem is worth
> addressing. The problem seems to me to be that we can't deduce a template
> parameter from the type of *this, because we don't have an explicit *this
> parameter. If we did, we could write:
>
>   template<typename T, typename U> using apply_cv_ref = /* apply cv- and
> ref-qualifiers from T to U */;
>
>   struct S {
>     template<typename T>
>     apply_cv_ref<T, int &&> f(T &&star_this, int n);
>   };
>
>   int g(int &&);
>   int h(int &);
>
>   int x = g(S().f(0)); // ok, f returns int &&
>   S s;
>   int y = h(s.f(0)); // ok, f returns int &
>
> As it is, we only have an "almost"-parameter tucked onto the end of the
> function type. My strawman suggestion is to use a template-template
> parameter to capture that parameter's type:
>
>   struct S {
>     template<template<typename> class Quals>
>     Quals<int> f(int n) Quals;
>
>     template<template<typename> class Quals>
>     Quals<int> transparent_access() Quals { return
> static_cast<Quals<int>>(x); }
>
>   private:
>     int x;
>   };
>
> Here, Quals will be deduced as a (built-in) alias template that applies the
> cv- and ref-qualifiers of *this to its type argument.
>
> Thoughts?
>

+1. I would propose that you can leave off the "template<....>" header
aswell. If you don't declare it, it becomes a "dual entity" that
behaves like an injected class name.

    auto transparent_access() Quals -> Quals<int> {
      Quals &&t = static_cast<Quals&&>(*this);
      // ...
    }

So if followed by a template argument list or passed to a template
template parameter, it is taken as a template-name. Otherwise, it is a
type-id that stands for the type (using decltype rules for
expressions) of the implied object argument.

--

---
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: Andrew Tomazos <andrewtomazos@gmail.com>
Date: Mon, 25 Aug 2014 22:39:23 +0200
Raw View
--089e0122aefaa2284f05017a2e34
Content-Type: text/plain; charset=UTF-8

On Mon, Aug 25, 2014 at 9:51 PM, Richard Smith <richard@metafoo.co.uk>
wrote:

> Why don't we make the following two syntaxes synonymous:
>>
>>     struct S { void f() const volatile &&; }
>>
>>     struct S { void f(const volatile S&& this); }
>>
>> that way we could do:
>>
>>     struct S { template<typename T> apply_cv_ref<T, int&&> f(T&& this,
>> int n); }
>>
>> like you want.  Or did I miss the point?
>>
>
> I don't actually want that =) I was merely observing why the *this
> qualifiers are a special case. I also think the result you get here is
> harder to use than my strawman proposal.
>

In order to use something, it must first be understood.  I think my version
is easier to understand than Quals, but lets not rush to judgement on
either.


> Also, wouldn't your approach make 'this' be a reference rather than a
> pointer? =)
>
> No, conceptually speaking it has a silent * prefix in the parameter
declaration.  The primary expression `this` remains a pointer as usual.

--

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

--089e0122aefaa2284f05017a2e34
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 25, 2014 at 9:51 PM, Richard Smith <span dir=3D"ltr">&lt;<a href=3D=
"mailto:richard@metafoo.co.uk" target=3D"_blank">richard@metafoo.co.uk</a>&=
gt;</span> wrote:<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;p=
adding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"=
gmail_quote">
<div><div class=3D"h5"><blockquote class=3D"gmail_quote" style=3D"margin:0p=
x 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);bo=
rder-left-style:solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gmai=
l_extra">
Why don&#39;t we make the following two syntaxes synonymous:</div><div clas=
s=3D"gmail_extra"><br></div><div class=3D"gmail_extra"><div class=3D"gmail_=
extra">=C2=A0 =C2=A0 struct S { void f() const volatile &amp;&amp;; }</div>

<div><br></div></div><div class=3D"gmail_extra">=C2=A0 =C2=A0 struct S { vo=
id f(const volatile S&amp;&amp; this); }</div><div class=3D"gmail_extra"><b=
r></div><div class=3D"gmail_extra">that way we could do:<br></div><div clas=
s=3D"gmail_extra">


<br></div><div class=3D"gmail_extra">=C2=A0 =C2=A0 struct S { template&lt;t=
ypename T&gt; apply_cv_ref&lt;T, int&amp;&amp;&gt; f(T&amp;&amp; this, int =
n); }</div><div class=3D"gmail_extra"><br></div><div class=3D"gmail_extra">=
like you want. =C2=A0Or did I miss the point?</div>

</div></blockquote><div><br></div></div></div><div>I don&#39;t actually wan=
t that =3D) I was merely observing why the *this qualifiers are a special c=
ase. I also think the result you get here is harder to use than my strawman=
 proposal.</div>
</div></div></div></blockquote><div><br></div><div>In order to use somethin=
g, it must first be understood. =C2=A0I think my version is easier to under=
stand than Quals, but lets not rush to judgement on either.</div><div>=C2=
=A0<br></div>
<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;p=
adding-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"=
gmail_quote">
<div></div><div>Also, wouldn&#39;t your approach make &#39;this&#39; be a r=
eference rather than a pointer? =3D)</div></div></div></div><div class=3D""=
><div class=3D"h5">

<p></p>

</div></div></blockquote></div></div><div class=3D"gmail_extra">No, concept=
ually speaking it has a silent * prefix in the parameter declaration. =C2=
=A0The primary expression `this` remains a pointer as usual.</div><div clas=
s=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 />

--089e0122aefaa2284f05017a2e34--

.


Author: sairony@gmail.com
Date: Mon, 25 Aug 2014 14:24:38 -0700 (PDT)
Raw View
------=_Part_464_1277215745.1409001878547
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



> [expr.prim.general]p3:
>
> "If a declaration declares a member function or member function template=
=20
> of a class X, the expression this
> is a prvalue of type =E2=80=9Cpointer to cv-qualifier-seq X=E2=80=9D betw=
een the optional=20
> cv-qualifer-seq and the end of the
> function-definition, member-declarator, or declarator. It shall not appea=
r=20
> before the optional cv-qualifier-seq
> and it shall not appear within the declaration of a static member functio=
n=20
> (although its type and value
> category are defined within a static member function as they are within a=
=20
> non-static member function)."
>
> =20
Ah, thanks. Wouldn't that wording permit this being used in the cv=20
qualifier for the member function though? As it's not technically before=20
but within it hehe :)

Personally I'm not a big fan of adding more template parameters for=20
controlling the cv qualifier of the function mostly because I believe it's=
=20
not as clean & easy to read as if const would behave as noexcept. Another=
=20
advantage / disadvantage would be that it would probably be unnatural to=20
not support such use of the cv qualifiers in all their contexts. Which I=20
think could be a big boon because I think it makes code once again clearer,=
=20
especially if you have an expression where you want to both select type,=20
select constness / volatile / mutable ( even though they're often mutually=
=20
exclusive ), you can then instead split it out to "const( /* expression for=
=20
const */ ) /* expression for deducing type */;", which is arguably easier=
=20
to break down and comprehend than nesting it all into one expression.

Kind regards,
Sebastian Karlsson

--=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_464_1277215745.1409001878547
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>[expr.prim.general]p3:</div><=
div><br></div><div><div>"If a declaration declares a member function or mem=
ber function template of a class X, the expression this</div><div>is a prva=
lue of type =E2=80=9Cpointer to cv-qualifier-seq X=E2=80=9D between the opt=
ional cv-qualifer-seq and the end of the</div>
<div>function-definition, member-declarator, or declarator. It shall not ap=
pear before the optional cv-qualifier-seq</div><div>and it shall not appear=
 within the declaration of a static member function (although its type and =
value</div>
<div>category are defined within a static member function as they are withi=
n a non-static member function)."</div></div><div><br></div></div></div></d=
iv></blockquote><div>&nbsp;</div><div>Ah, thanks. Wouldn't that wording per=
mit this being used in the cv qualifier for the member function though? As =
it's not technically before but within it hehe :)</div><div><br></div><div>=
Personally I'm not a big fan of adding more template parameters for control=
ling the cv qualifier of the function mostly because I believe it's not as =
clean &amp; easy to read as if const would behave as noexcept. Another adva=
ntage / disadvantage would be that it would probably be unnatural to not su=
pport such use of the cv qualifiers in all their contexts. Which I think co=
uld be a big boon because I think it makes code once again clearer, especia=
lly if you have an expression where you want to both select type, select co=
nstness / volatile / mutable ( even though they're often mutually exclusive=
 ), you can then instead split it out to "const( /* expression for const */=
 ) /* expression for deducing type */;", which is arguably easier to break =
down and comprehend than nesting it all into one expression.</div><div><br>=
</div><div>Kind regards,</div><div>Sebastian Karlsson</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_464_1277215745.1409001878547--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Mon, 25 Aug 2014 14:53:22 -0700
Raw View
On Monday 25 August 2014 12:48:40 Richard Smith wrote:
> > > >
> > > > template <typename T>
> > > > constexpr(std::is_integral<T>::value) T align_down(T x, size_t a)
> > > > noexcept(std::is_integral<T>::value);
> > >
> > > I don't see any value in this; just mark the template as 'constexpr'. If
> >
> > a
> >
> > > particular specialization doesn't satisfy the relevant requirements,
> >
> > that's
> >
> > > fine (you simply can't use that specialization in a constant
> > > expression).
> >
> > The point is that the function should be allowed for that condition, the
> > same
> > way that noexcept does.
>
> That's what you get today if you use 'constexpr'. What am I missing?

Come to think of it, nothing. Template constexprs are allowed to not be
constexpr :-)

We're still missing the ability to overload a constexpr function for compile-
time with a non-constexpr version for runtime, though.

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

.