220 6052 <d9734fdc-c3d2-4529-b573-75504f90b28b@isocpp.org> article
Path: news.gmane.org!not-for-mail
From: Artyom Lebedev <artyom.lebedev@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Templates usage with *this
Date: Sat, 31 Aug 2013 10:33:33 -0700 (PDT)
Lines: 822
Approved: news@gmane.org
Message-ID: <d9734fdc-c3d2-4529-b573-75504f90b28b@isocpp.org>
References: <e0049c1d-1b02-42bc-a871-2f5749572c41@isocpp.org>
 <CABbCQwtBF5Q9ah_Ygz1btF_KVgLYPs-fgWn91j_AB9DLaRxtFg@mail.gmail.com>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: plane.gmane.org
Mime-Version: 1.0
Content-Type: multipart/alternative; 
	boundary="----=_Part_99_5311462.1377970413676"
X-Trace: ger.gmane.org 1377970413 8544 80.91.229.3 (31 Aug 2013 17:33:33 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Sat, 31 Aug 2013 17:33:33 +0000 (UTC)
To: std-proposals@isocpp.org
Original-X-From: std-proposals+bncBC4KXOVK3ENRB3WRRCIQKGQESYLXLZY@isocpp.org Sat Aug 31 19:33:36 2013
Return-path: <std-proposals+bncBC4KXOVK3ENRB3WRRCIQKGQESYLXLZY@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-vc0-f198.google.com ([209.85.220.198])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBC4KXOVK3ENRB3WRRCIQKGQESYLXLZY@isocpp.org>)
	id 1VFp3H-0002mo-EQ
	for gclcip-std-proposals@m.gmane.org; Sat, 31 Aug 2013 19:33:35 +0200
Original-Received: by mail-vc0-f198.google.com with SMTP id ht10sf3465459vcb.9
        for <gclcip-std-proposals@m.gmane.org>; Sat, 31 Aug 2013 10:33:34 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20120113;
        h=date:from:to:message-id:in-reply-to:references:subject:mime-version
         :x-original-sender:reply-to:precedence:mailing-list:list-id
         :list-post:list-help:list-archive:list-subscribe:list-unsubscribe
         :content-type;
        bh=MPyKmuFfRYmy0cxdhkU7q9hFC7Zi9jGSLGfQ8nq+5Zo=;
        b=j+TBbe3ItwT5ZrunfLeNXZPbvWmCoNrQIeS57fJd1iIFRkIE8SAXWDPqMilnniiutB
         scOvoBpopujpPDa9/vgQMeKiaFmwhhlp8X3UtjhLGlqq0Gyh63e0pwdid5xZqiweHi4/
         GbfKNptpfZjDOrs9POCXNs1VHA24pDsMdg0LBH4Ke81zj0KXUGPePgAislZWWtXybrtd
         AWYQjdRlzf8bEWnYcYwdc8xVKHHaoRmK4sJdGOF+T3ox1qzJjS6XrhAofPKnBvxQb0yc
         aAvI3rtPDXAkK6B16mJkztoLdc6YmjTDf1eGWtWXoUBdqbokgQFyVD/OJPdjXsbBwTK5
         +Oag==
X-Received: by 10.236.103.97 with SMTP id e61mr1075592yhg.31.1377970414560;
        Sat, 31 Aug 2013 10:33:34 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.49.26.102 with SMTP id k6ls1127451qeg.5.gmail; Sat, 31 Aug
 2013 10:33:34 -0700 (PDT)
X-Received: by 10.49.30.8 with SMTP id o8mr214qeh.36.1377970414036;
        Sat, 31 Aug 2013 10:33:34 -0700 (PDT)
In-Reply-To: <CABbCQwtBF5Q9ah_Ygz1btF_KVgLYPs-fgWn91j_AB9DLaRxtFg@mail.gmail.com>
X-Original-Sender: artyom.lebedev@gmail.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Google-Group-Id: 399137483710
List-Post: <http://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <http://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <http://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:6052
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/6052>

------=_Part_99_5311462.1377970413676
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable


>
> I'm not sure if it'd be better or not to make it a template (I haven't pu=
t=20
> very much thought into it yet), but I just wanted to mention this option.
>
I definitely sure that it must be a template. Basically we have a function=
=20
template which has "this" implicit argument type as a template parameter,=
=20
i.e. depending on the provided "this" argument type different function code=
=20
is instantiated - this is true for this case and it is how templates work.=
=20
Also examples below in this message will show, how it is close to usual=20
templatized argument.

Also, there needs to be some way to specify you only want to define all the=
=20
> & versions but not the && versions, or only the const versions. Something=
=20
> like:
>
> void whatever() T & { ... }
> void whatever() T const { ... }
>
> This would make repeating the template paramaeter name after the argument=
=20
> list non-redundant in your template idea.
>

Think about it as it would be a regular function, for example, with such=20
definition:
template <class ThisType>
void
Method(ThisType &&thisRef)
{
// thisRef is *this
}
which could have such equivalent:
template <this ThisType>
void
Method() &&
{
}
As I have written before, all rules for types matching and deduction for=20
arguments should work for this case. In such case, this example would match=
=20
both "const ThisType &" (ThisType deduced to "const ClassType &" and=20
"ThisType &&" (ThisType deduced to "ClassType") , and "ThisType &"=20
(ThisType deduced to "ClassType &") - in the way it is described in=20
std::forward example: http://en.cppreference.com/w/cpp/utility/forward. So,=
=20
in other example:
template <this ThisType>
void
Method() & //think it is Method(ThisType &)
{
}
the method will match only "[const and/or volatile] ThisType &" and=20
"ThisType &" (deducing to the "const and/or volatile ClassType" and=20
"ClassType"), not "ThisType &&" (which should produce the same error, e.g.=
=20
in GCC - "invalid initialization of non-const reference of type =91... &=92=
=20
from an rvalue of type ..."), just like it would be if it was written as=20
argument:
template <class ThisType>
void
Method(ThisType &thisRef)
{
// thisRef is *this
}

So what I want to say, is that CV-qualifiers and lvalue/rvalue reference=20
after parenthesis is just a syntactic sugar for the case if "this" argument=
=20
was explicit and was written inside parenthesis and with the name. And=20
still seems that the name is not needed there because we always know what=
=20
and where it is. Correct me if I'm wrong.

Maurice Bos:
>
> Hello,
>
> I've been thinking about the same problem a few weeks ago. I was writing =
a=20
> blog post about 'rvalue references for *this' (aka &&-member functions), =
in=20
> which I also complained a bit about how annoying it is to define an=20
> accessor properly (&, const &, &&, const &&, etc.) (
> http://blog.m-ou.se/2013/07/21/rvalue-references-for-this.html). The=20
> suggestion I gave had to 'fix' this, is similar to yours:
>
> class foo {
>     std::string name_;
> public:
>     decltype(auto) name() T && { return std::forward<T>(*this).name_; }
> }:
>
> However, there's one big difference with your solution: Here, foo::name()=
=20
> is not a template. This syntax just and defines 8 different versions of=
=20
> foo::name (the &, const &, volatile &, const volatile &, and all the &&=
=20
> versions).
>
> I'm not sure if it'd be better or not to make it a template (I haven't pu=
t=20
> very much thought into it yet), but I just wanted to mention this option.
>
> Also, there needs to be some way to specify you only want to define all=
=20
> the & versions but not the && versions, or only the const versions.=20
> Something like:
>
> void whatever() T & { ... }
> void whatever() T const { ... }
>
> This would make repeating the template paramaeter name after the argument=
=20
> list non-redundant in your template idea.
>
> -Maurice-
>
>
>
>
>
> 2013/8/31 <artyom....@gmail.com <javascript:>>
>
>> Hi,
>>
>> This in not a well-formed proposal but just my thoughts about the subjec=
t=20
>> feature. May be something similar is already planned but I did not find =
it=20
>> in C++14 features list.
>>
>>
>>  So now, especially after introducing =93N2439 - Extending move semantic=
s=20
>> to *this=94, (*this) can be matched to differently qualified type:
>>
>>
>> class A {
>>
>>     void Method(); // 1. *this is "A&"
>>
>>     void Method() const; // 2. *this is "const A&"
>>
>>     void Method() volatile; // 3. *this is "volatile A&"
>>
>>     void Method() const volatile; // 4. *this is "const volatile A&"
>>
>>     void Method() &&; //5. matched to "A &&" but in scope of method=20
>> implementation *this is "A&" since it has name
>>
>>     void Method() const &&; //6. This one and similar CV+rvalue_ref, may=
=20
>> be not so meaningful in most cases but still worth to mention. *this is=
=20
>> "const A&", probably always matches "A&&".
>>
>> };
>>
>>
>>  Currently there is no way to create a method template, having type of=
=20
>> =93*this=94 as template parameter. In some cases you might want to have =
generic=20
>> implementation for a method and properly forward =93*this=94 to some oth=
er=20
>> function. The number of combinations for *this types reminds me the=20
>> situation with possible qualifiers for arguments in templates before=20
>> perfect forwarding pattern was introduced. Fortunately, now we have only=
=20
>> one problematic argument with dozen of choices (which were doubled after=
=20
>> N2439).
>>
>>
>>  Small real world example of the applicable situation. Let's say I have=
=20
>> a class which encapsulates some value. The value has dynamic type, and m=
ay=20
>> have underlying type which requires heap allocation (e.g. string) so it =
is=20
>> perfect for moving. I have method Get<TargetType>() which returns the=20
>> value. The trick with the Get() method is that for =93rvalue *this=94 we=
 can=20
>> move the stored value to the result returned to the caller (and this is=
=20
>> very cool language feature indeed).
>>
>>
>>  class Value {
>>
>>
>>      template <typename T>
>>
>>     T
>>
>>     Get() const &
>>
>>     {
>>
>>         // return a copy of the stored value
>>
>>     }
>>
>>
>>      template <typename T>
>>
>>     T
>>
>>     Get() &&
>>
>>     {
>>
>>         // move the stored value to the returned result
>>
>>     }
>>
>>
>>      // And here we might want to have some aliases
>>
>>     template <typename T>
>>
>>     operator T() const &
>>
>>     {
>>
>>         return Get<T>();
>>
>>     }
>>
>>
>>      template <typename T>
>>
>>     operator T() &&
>>
>>     {
>>
>>         return std::move(*this).Get<T>();
>>
>>     }
>>
>>
>>      template <typename T>
>>
>>     T
>>
>>     GetWithStuff() const &
>>
>>     {
>>
>>         return Get<T>() + Stuff<T>();
>>
>>     }
>>
>>
>>      template <typename T>
>>
>>     T
>>
>>     GetWithStuff() &&
>>
>>     {
>>
>>         return std::move(*this).Get<T>() + Stuff<T>();
>>
>>     }
>> =20
>> };
>>
>>
>>  The problem is that Get() method has some aliases (it might be another=
=20
>> method with just different name or some generalized additional logic, or=
,=20
>> for example, type casting operator). Did you also noticed copy-pasting=
=20
>> which naturally seems must be avoided? What I basically might want from =
the=20
>> language, is the ability to perfectly forward =93*this=94 to some functi=
ons.=20
>> Possible syntax (just the first idea):
>>
>>
>>  template <this ThisType, typename T>
>>
>> T
>>
>> GetWithStuff() ThisType && //roughly equivalent to "T&&" in arguments=20
>> when using arguments forwarding
>>
>> {
>>
>>     return std::forward<ThisType>(*this).Get<T>() + Stuff<T>();
>>
>> }
>>
>>
>>  I think =93this=94 keyword can be used in template parameters which is =
very=20
>> natural. Also I feel that all rules applicable to type deduction of=20
>> argument in =93T &&=94 form (in perfect forwarding pattern context), as =
well as=20
>> all rules for argument types and templates there, should be the same for=
=20
>> =93this=94 argument which is just written next to parenthesis. Thus such=
=20
>> construction
>>
>>
>>  template <this ThisType, typename T>
>>
>> T
>>
>> GetWithStuff() const ThisType &
>>
>> {
>>
>>     return std::forward<ThisType>(*this).Get<T>() + Stuff<T>();
>>
>> }
>>
>>
>>  will not have much sense (ThisType will be just =93Value=94) but still=
=20
>> should work to make things consistent.
>>
>>
>>  May be having template parameter name in =93*this=94 specification part=
 is=20
>> redundant:
>>
>> template <this ThisType, typename T>
>>
>> T
>>
>> GetWithStuff() const & //presence of "this" in template parameters=20
>> automatically applies it there
>>
>> {
>>
>>     return std::forward<ThisType>(*this).Get<T>() + Stuff<T>();
>>
>> }
>>
>>
>>  Obviously =93this=94 can be used in template parameters for non-static=
=20
>> class methods only.
>>
>>
>>  IMHO such feature would be a nice addition for making the language even=
=20
>> more beautiful, and it should not be a problem to implement in compilers=
=20
>> since =93this=94 argument already should be implicitly present (with typ=
e=20
>> information) in most places, which are subject for the changes.
>>
>>
>> Best regards,
>>
>> Artyom
>> =20
>> --=20
>> =20
>> ---=20
>> You received this message because you are subscribed to the Google Group=
s=20
>> "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this group and stop receiving emails from it, send a=
n=20
>> email to std-proposal...@isocpp.org <javascript:>.
>> To post to this group, send email to std-pr...@isocpp.org <javascript:>.
>> Visit this group at=20
>> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>>
>
>

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_99_5311462.1377970413676
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><blockquote style=3D"margin: 0px 0px 0px 0.8ex; border-lef=
t: 1px solid rgb(204, 204, 204); padding-left: 1ex;" class=3D"gmail_quote">=
I'm not sure if it'd be better or not to make it a template (I haven't=20
put very much thought into it yet), but I just wanted to mention this=20
option.<br></blockquote>I definitely sure that it must be a template. Basic=
ally we have a function template which has "this" implicit argument type as=
 a template parameter, i.e. depending on the provided "this" argument type =
different function code is instantiated - this is true for this case and it=
 is how templates work. Also examples below in this message will show, how =
it is close to usual templatized argument.<br><br><blockquote style=3D"marg=
in: 0px 0px 0px 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-l=
eft: 1ex;" class=3D"gmail_quote">Also, there needs to be some way to specif=
y you only want to define all=20
the &amp; versions but not the &amp;&amp; versions, or only the const=20
versions. Something like:<br>

<br>void whatever() T &amp; { ... }<br>void whatever() T const { ... }<br><=
br>This would make repeating the template paramaeter name after the argumen=
t list non-redundant in your template idea.<br></blockquote><br>Think about=
 it as it would be a regular function, for example, with such definition:<b=
r><span style=3D"font-family: courier new,monospace;">template &lt;class Th=
isType&gt;<br>void<br>Method(ThisType &amp;&amp;thisRef)<br>{<br>// thisRef=
 is *this<br>}</span><br>which could have such equivalent:<br><span style=
=3D"font-family: courier new,monospace;">template &lt;this ThisType&gt;<br>=
void<br>Method() &amp;&amp;<br>{<br>}</span><br>As I have written before, a=
ll rules for types matching and deduction for arguments should work for thi=
s case. In such case, this example would match both "const ThisType &amp;" =
(ThisType deduced to "const ClassType &amp;" and "ThisType &amp;&amp;" (Thi=
sType deduced to "ClassType") , and "ThisType &amp;" (ThisType deduced to "=
ClassType &amp;") - in the way it is described in std::forward example: htt=
p://en.cppreference.com/w/cpp/utility/forward. So, in other example:<br><sp=
an style=3D"font-family: courier new,monospace;">template &lt;this ThisType=
&gt;<br>void<br>Method() &amp; //think it is Method(ThisType &amp;)<br>{<br=
>}</span><br>the method will match only "[const and/or volatile] ThisType &=
amp;" and "ThisType &amp;" (deducing to the "const and/or volatile ClassTyp=
e" and "ClassType"), not "ThisType &amp;&amp;" (which should produce the sa=
me error, e.g. in GCC - "invalid initialization of non-const reference of t=
ype =91... &amp;=92 from an rvalue of type ..."), just like it would be if =
it was written as argument:<br><span style=3D"font-family: courier new,mono=
space;">template &lt;class ThisType&gt;<br>void<br>Method(ThisType &amp;thi=
sRef)<br>{<br>// thisRef is *this<br>}</span><br><br>So what I want to say,=
 is that CV-qualifiers and lvalue/rvalue reference after parenthesis is jus=
t a syntactic sugar for the case if "this" argument was explicit and was wr=
itten inside parenthesis and with the name. And still seems that the name i=
s not needed there because we always know what and where it is. Correct me =
if I'm wrong.<br><br>Maurice Bos:<blockquote class=3D"gmail_quote" style=3D=
"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex=
;"><div dir=3D"ltr">Hello,<br><br>I've been thinking about the same problem=
 a few weeks ago. I was writing a blog post about 'rvalue references for *t=
his' (aka &amp;&amp;-member functions), in which I also complained a bit ab=
out how annoying it is to define an accessor properly (&amp;, const &amp;, =
&amp;&amp;, const &amp;&amp;, etc.) (<a href=3D"http://blog.m-ou.se/2013/07=
/21/rvalue-references-for-this.html" target=3D"_blank">http://blog.m-ou.se/=
2013/07/<wbr>21/rvalue-references-for-this.<wbr>html</a>). The suggestion I=
 gave had to 'fix' this, is similar to yours:<br>

<br>class foo {<br>&nbsp; &nbsp; std::string name_;<br>public:<br>&nbsp; &n=
bsp; decltype(auto) name() T &amp;&amp; { return std::forward&lt;T&gt;(*thi=
s).name_; }<br>}:<br><br>However, there's one big difference with your solu=
tion: Here, foo::name() is not a template. This syntax just and defines 8 d=
ifferent versions of foo::name (the &amp;, const &amp;, volatile &amp;, con=
st volatile &amp;, and all the &amp;&amp; versions).<br>

<br>I'm not sure if it'd be better or not to make it a template (I haven't =
put very much thought into it yet), but I just wanted to mention this optio=
n.<br><br>Also, there needs to be some way to specify you only want to defi=
ne all the &amp; versions but not the &amp;&amp; versions, or only the cons=
t versions. Something like:<br>

<br>void whatever() T &amp; { ... }<br>void whatever() T const { ... }<br><=
br>This would make repeating the template paramaeter name after the argumen=
t list non-redundant in your template idea.<br><br>-Maurice-<br><br><pre><c=
ode><span><br></span></code></pre><br></div><div><br><br><div class=3D"gmai=
l_quote">2013/8/31  <span dir=3D"ltr">&lt;<a href=3D"javascript:" target=3D=
"_blank" gdf-obfuscated-mailto=3D"M_HsX-4ZM5cJ">artyom....@gmail.com</a>&gt=
;</span><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">


=09
=09
=09
=09


<p style=3D"margin-bottom:0in">Hi,</p>
<p style=3D"margin-bottom:0in">This in not a well-formed proposal but
just my thoughts about the subject feature. May be something similar is alr=
eady planned but I did not find it in C++14 features list.<br></p>
<p style=3D"margin-bottom:0in"><br>
</p>
<p style=3D"margin-bottom:0in">So now, especially after introducing
=93N2439 - Extending move semantics to *this=94, (*this) can be
matched to differently qualified type:</p><p style=3D"margin-bottom:0in"><b=
r></p>
<p style=3D"margin-bottom:0in"><span style=3D"font-family:courier new,monos=
pace">class A {</span></p><span style=3D"font-family:courier new,monospace"=
>
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp; void Method(); // 1. *this is "A&amp;"</spa=
n></p><span style=3D"font-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp; void Method() const;  // 2. *this is "const=
 A&amp;"</span></p><span style=3D"font-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp; void Method() volatile;  // 3. *this is "vo=
latile A&amp;"</span></p><span style=3D"font-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp; void Method() const volatile; // 4.
*this is "const volatile A&amp;"</span></p><span style=3D"font-family:couri=
er new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp; void Method() &amp;&amp;; //5. matched
to "A &amp;&amp;" but in scope of method implementation *this is "A&amp;" s=
ince it has name</span></p><span style=3D"font-family:courier new,monospace=
">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp; void Method() const &amp;&amp;; //6.
This one and similar CV+rvalue_ref, may be not so meaningful in most
cases but still worth to mention. *this is "const A&amp;",
probably always matches "A&amp;&amp;".</span></p><span style=3D"font-family=
:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">};</span></p>
<p style=3D"margin-bottom:0in"><br>
</p>
<p style=3D"margin-bottom:0in">Currently there is no way to create a
method template, having type of =93*this=94 as template parameter. In
some cases you might want to have generic implementation for a method
and properly forward =93*this=94 to some other function. The number
of combinations for *this types reminds me the situation with
possible qualifiers for arguments in templates before perfect
forwarding pattern was introduced. Fortunately, now we have only one
problematic argument with dozen of choices (which were doubled after N2439)=
..</p>
<p style=3D"margin-bottom:0in"><br>
</p>
<p style=3D"margin-bottom:0in">Small real world example of the applicable
situation. Let's say I have a class which encapsulates some value.
The value has dynamic type, and may have underlying type which
requires heap allocation (e.g. string) so it is perfect for moving. I
have method Get&lt;TargetType&gt;() which returns the value. The
trick with the Get() method is that for =93rvalue *this=94 we can
move the stored value to the result returned to the caller (and this is
very cool language feature indeed).</p>
<p style=3D"margin-bottom:0in"><br>
</p>
<p style=3D"margin-bottom:0in"><span style=3D"font-family:courier new,monos=
pace">class Value {</span></p><span style=3D"font-family:courier new,monosp=
ace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace"><br></span>
</p><span style=3D"font-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp; template &lt;typename T&gt;</span></p><span=
 style=3D"font-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp; T</span></p><span style=3D"font-family:cour=
ier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp; Get() const &amp;</span></p><span style=3D"=
font-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp; {</span></p><span style=3D"font-family:cour=
ier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // return a copy of=
 the stored value</span></p><span style=3D"font-family:courier new,monospac=
e">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp; }</span></p><span style=3D"font-family:cour=
ier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace"><br></span>
</p><span style=3D"font-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp; template &lt;typename T&gt;</span></p><span=
 style=3D"font-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp; T</span></p><span style=3D"font-family:cour=
ier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp; Get() &amp;&amp;</span></p><span style=3D"f=
ont-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp; {</span></p><span style=3D"font-family:cour=
ier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // move the stored =
value to the returned
result</span></p><span style=3D"font-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp; }</span></p><span style=3D"font-family:cour=
ier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace"><br></span>
</p><span style=3D"font-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp; // And here we might want to have some
aliases</span></p><span style=3D"font-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp; template &lt;typename T&gt;</span></p><span=
 style=3D"font-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp; operator T() const &amp;</span></p><span st=
yle=3D"font-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp; {</span></p><span style=3D"font-family:cour=
ier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return Get&lt;T&gt;=
();</span></p><span style=3D"font-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp; }</span></p><span style=3D"font-family:cour=
ier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace"><br></span>
</p><span style=3D"font-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp; template &lt;typename T&gt;</span></p><span=
 style=3D"font-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp; operator T() &amp;&amp;</span></p><span sty=
le=3D"font-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp; {</span></p><span style=3D"font-family:cour=
ier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return std::move(*t=
his).Get&lt;T&gt;();</span></p><span style=3D"font-family:courier new,monos=
pace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp; }</span></p><span style=3D"font-family:cour=
ier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace"><br></span>
</p><span style=3D"font-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp; template &lt;typename T&gt;</span></p><span=
 style=3D"font-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp; T</span></p><span style=3D"font-family:cour=
ier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp; GetWithStuff() const &amp;</span></p><span =
style=3D"font-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp; {</span></p><span style=3D"font-family:cour=
ier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return Get&lt;T&gt;=
() + Stuff&lt;T&gt;();</span></p><span style=3D"font-family:courier new,mon=
ospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp; }</span></p><span style=3D"font-family:cour=
ier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace"><br></span>
</p><span style=3D"font-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp; template &lt;typename T&gt;</span></p><span=
 style=3D"font-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp; T</span></p><span style=3D"font-family:cour=
ier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp; GetWithStuff() &amp;&amp;</span></p><span s=
tyle=3D"font-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp; {</span></p><span style=3D"font-family:cour=
ier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;	return std::move(*t=
his).Get&lt;T&gt;()
+ Stuff&lt;T&gt;();</span></p><span style=3D"font-family:courier new,monosp=
ace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp; }</span></p><span style=3D"font-family:cour=
ier new,monospace">
</span><span style=3D"font-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">};</span></p>
<p style=3D"margin-bottom:0in"><br>
</p>
<p style=3D"margin-bottom:0in">The problem is that Get() method has
some aliases (it might be another method with just different name or
some generalized additional logic, or, for example, type casting
operator). Did you also noticed copy-pasting which naturally seems
must be avoided? What I basically might want from the language, is
the ability to perfectly forward =93*this=94 to some functions.
Possible syntax (just the first idea):</p>
<p style=3D"margin-bottom:0in"><br>
</p>
<p style=3D"margin-bottom:0in"><span style=3D"font-family:courier new,monos=
pace">template &lt;this ThisType, typename T&gt;</span></p><span style=3D"f=
ont-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">T</span></p><span style=3D"font-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">GetWithStuff() ThisType &amp;&amp;
//roughly equivalent to "T&amp;&amp;" in arguments when using
arguments forwarding</span></p><span style=3D"font-family:courier new,monos=
pace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">{</span></p><span style=3D"font-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp; return
std::forward&lt;ThisType&gt;(*this).<wbr>Get&lt;T&gt;() + Stuff&lt;T&gt;();=
</span></p><span style=3D"font-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">}</span></p><span style=3D"font-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><br>
</p>
<p style=3D"margin-bottom:0in">I think =93this=94 keyword can be used
in template parameters which is very natural. Also I feel that all
rules applicable to type deduction of argument in =93T &amp;&amp;=94
form (in perfect forwarding pattern context), as well as all rules
for argument types and templates there, should be the same for =93this=94
argument which is just written next to parenthesis. Thus such
construction</p>
<p style=3D"margin-bottom:0in"><br>
</p>
<p style=3D"margin-bottom:0in"><span style=3D"font-family:courier new,monos=
pace">template &lt;this ThisType, typename T&gt;</span></p><span style=3D"f=
ont-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">T</span></p><span style=3D"font-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">GetWithStuff() const ThisType &amp;</span></p><span style=3D"f=
ont-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">{</span></p><span style=3D"font-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp; return
std::forward&lt;ThisType&gt;(*this).<wbr>Get&lt;T&gt;() + Stuff&lt;T&gt;();=
</span></p><span style=3D"font-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">}</span></p>
<p style=3D"margin-bottom:0in"><br>
</p>
<p style=3D"margin-bottom:0in">will not have much sense (ThisType will
be just =93Value=94) but still should work to make things consistent.</p>
<p style=3D"margin-bottom:0in"><br>
</p>
<p style=3D"margin-bottom:0in">May be having template parameter name
in =93*this=94 specification part is redundant:</p>
<p style=3D"margin-bottom:0in"><span style=3D"font-family:courier new,monos=
pace">template &lt;this ThisType, typename T&gt;</span></p><span style=3D"f=
ont-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">T</span></p><span style=3D"font-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">GetWithStuff() const &amp; //presence
of "this" in template parameters automatically applies it there</span></p><=
span style=3D"font-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">{</span></p><span style=3D"font-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp; return
std::forward&lt;ThisType&gt;(*this).<wbr>Get&lt;T&gt;() + Stuff&lt;T&gt;();=
</span></p><span style=3D"font-family:courier new,monospace">
</span><p style=3D"margin-bottom:0in"><span style=3D"font-family:courier ne=
w,monospace">}</span></p>
<p style=3D"margin-bottom:0in"><br>
</p>
<p style=3D"margin-bottom:0in">Obviously =93this=94 can be used in
template parameters for non-static class methods only.</p>
<p style=3D"margin-bottom:0in"><br>
</p>
<p style=3D"margin-bottom:0in">IMHO such feature would be a nice
addition for making the language even more beautiful, and it should
not be a problem to implement in compilers since =93this=94 argument
already should be implicitly present (with type information) in most
places, which are subject for the changes.</p><p style=3D"margin-bottom:0in=
"><br></p><p style=3D"margin-bottom:0in">Best regards,</p><p style=3D"margi=
n-bottom:0in">Artyom<span><font color=3D"#888888"><br></font></span></p>

</div><span><font color=3D"#888888">

<p></p>

-- <br>
&nbsp;<br>
--- <br>
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"=
M_HsX-4ZM5cJ">std-proposal...@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"javascript:" target=3D"_bla=
nk" gdf-obfuscated-mailto=3D"M_HsX-4ZM5cJ">std-pr...@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/<wbr>isocpp.or=
g/group/std-<wbr>proposals/</a>.<br>
</font></span></blockquote></div><br></div>
</blockquote></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_99_5311462.1377970413676--

.
