220 6046 <e0049c1d-1b02-42bc-a871-2f5749572c41@isocpp.org> article
Path: news.gmane.org!not-for-mail
From: artyom.lebedev@gmail.com
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Templates usage with *this
Date: Sat, 31 Aug 2013 01:25:54 -0700 (PDT)
Lines: 575
Approved: news@gmane.org
Message-ID: <e0049c1d-1b02-42bc-a871-2f5749572c41@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: plane.gmane.org
Mime-Version: 1.0
Content-Type: multipart/alternative; 
	boundary="----=_Part_766_28935819.1377937554942"
X-Trace: ger.gmane.org 1377960272 8203 80.91.229.3 (31 Aug 2013 14:44:32 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Sat, 31 Aug 2013 14:44:32 +0000 (UTC)
To: std-proposals@isocpp.org
Original-X-From: std-proposals+bncBC4KXOVK3ENRBTMCRCIQKGQEXKJYELI@isocpp.org Sat Aug 31 16:44:33 2013
Return-path: <std-proposals+bncBC4KXOVK3ENRBTMCRCIQKGQEXKJYELI@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-vc0-f199.google.com ([209.85.220.199])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBC4KXOVK3ENRBTMCRCIQKGQEXKJYELI@isocpp.org>)
	id 1VFmPf-0003Kz-4f
	for gclcip-std-proposals@m.gmane.org; Sat, 31 Aug 2013 16:44:31 +0200
Original-Received: by mail-vc0-f199.google.com with SMTP id gf11sf3331580vcb.10
        for <gclcip-std-proposals@m.gmane.org>; Sat, 31 Aug 2013 07:44:30 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20120113;
        h=date:from:to:message-id: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=OdtbLM/QhJ6ks3PVKLkhPOM6C/C6xs+TNOQcWu/PhnA=;
        b=Gi3HqKEY317xyCNtxa8YWf0x63nH0DrB2tr5nOJYwMO5s/2cp81u6XbupwWvoshdNC
         yEz9+ZnxOLnvKF+mTTrNiPrK8666zWplyUD338b+QwI9luC0L/9JVGyeGCissQLdWRRm
         6ffz9qGSxaGWneseDPSsLPH6G+oVyLNBbg6GVPP+yNE1MH+F6tws77T/UiQTLTTGsxJW
         5lRVfgXlqpZo3a3vX/HqFnrvanBfkKY/2z8a5U/87vfDTeKoWGad4GlO3+7NkqBCCs9T
         9Ke9SNwzGUZXO0EAfacQ0ZpOrlyHkNP/NUj9LSmNA5xRtueMCDLsgwhhUfivdEJgOPgj
         Qh/w==
X-Received: by 10.236.163.67 with SMTP id z43mr4939809yhk.27.1377960270019;
        Sat, 31 Aug 2013 07:44:30 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.49.30.35 with SMTP id p3ls1677527qeh.97.gmail; Sat, 31 Aug
 2013 07:44:29 -0700 (PDT)
X-Received: by 10.224.36.198 with SMTP id u6mr15433645qad.6.1377960269399;
        Sat, 31 Aug 2013 07:44:29 -0700 (PDT)
Original-Received: by 10.224.165.72 with SMTP id h8msqay;
        Sat, 31 Aug 2013 01:25:55 -0700 (PDT)
X-Received: by 10.49.104.148 with SMTP id ge20mr508729qeb.2.1377937555325;
        Sat, 31 Aug 2013 01:25:55 -0700 (PDT)
X-Original-Sender: artyomlebedev@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:6046
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/6046>

------=_Part_766_28935819.1377937554942
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

=20

Hi,

This in not a well-formed proposal but just my thoughts about the subject=
=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 semantics t=
o=20
*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 be=
=20
not so meaningful in most cases but still worth to mention. *this is "const=
=20
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 gen=
eric=20
implementation for a method and properly forward =93*this=94 to some other=
=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 a=
=20
class which encapsulates some value. The value has dynamic type, and may=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 ca=
n=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 functions=
..=20
Possible syntax (just the first idea):


 template <this ThisType, typename T>

T

GetWithStuff() ThisType && //roughly equivalent to "T&&" in arguments when=
=20
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 ver=
y=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 wel=
l 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 sho=
uld=20
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 cla=
ss=20
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 type=
=20
information) in most places, which are subject for the changes.


Best regards,

Artyom

--=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_766_28935819.1377937554942
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">


=09
=09
=09
	<style type=3D"text/css">P { margin-bottom: 0.08in; }</style>


<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"><=
br></p>
<p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier new,mon=
ospace;">class A {</span></p><span style=3D"font-family: courier new,monosp=
ace;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,monospace;">&nbsp;&nbsp;&nbsp; void Method(); // 1. *this is "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 =
new,monospace;">&nbsp;&nbsp;&nbsp; void Method() const;  // 2. *this is "co=
nst 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 =
new,monospace;">&nbsp;&nbsp;&nbsp; void Method() volatile;  // 3. *this is =
"volatile A&amp;"</span></p><span style=3D"font-family: courier new,monospa=
ce;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,monospace;">&nbsp;&nbsp;&nbsp; void Method() const volatile; // 4.
*this is "const volatile A&amp;"</span></p><span style=3D"font-family: cour=
ier new,monospace;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,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,monospac=
e;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,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 =
new,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,mon=
ospace;">class Value {</span></p><span style=3D"font-family: courier new,mo=
nospace;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,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 =
new,monospace;">&nbsp;&nbsp;&nbsp; template &lt;typename T&gt;</span></p><s=
pan style=3D"font-family: courier new,monospace;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,monospace;">&nbsp;&nbsp;&nbsp; T</span></p><span style=3D"font-family: =
courier new,monospace;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,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 =
new,monospace;">&nbsp;&nbsp;&nbsp; {</span></p><span style=3D"font-family: =
courier new,monospace;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // return a copy=
 of the stored value</span></p><span style=3D"font-family: courier new,mono=
space;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,monospace;">&nbsp;&nbsp;&nbsp; }</span></p><span style=3D"font-family: =
courier new,monospace;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,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 =
new,monospace;">&nbsp;&nbsp;&nbsp; template &lt;typename T&gt;</span></p><s=
pan style=3D"font-family: courier new,monospace;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,monospace;">&nbsp;&nbsp;&nbsp; T</span></p><span style=3D"font-family: =
courier new,monospace;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,monospace;">&nbsp;&nbsp;&nbsp; Get() &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 =
new,monospace;">&nbsp;&nbsp;&nbsp; {</span></p><span style=3D"font-family: =
courier new,monospace;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // move the stor=
ed 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 =
new,monospace;">&nbsp;&nbsp;&nbsp; }</span></p><span style=3D"font-family: =
courier new,monospace;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,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 =
new,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 =
new,monospace;">&nbsp;&nbsp;&nbsp; template &lt;typename T&gt;</span></p><s=
pan style=3D"font-family: courier new,monospace;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,monospace;">&nbsp;&nbsp;&nbsp; operator T() 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 =
new,monospace;">&nbsp;&nbsp;&nbsp; {</span></p><span style=3D"font-family: =
courier new,monospace;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,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 =
new,monospace;">&nbsp;&nbsp;&nbsp; }</span></p><span style=3D"font-family: =
courier new,monospace;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,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 =
new,monospace;">&nbsp;&nbsp;&nbsp; template &lt;typename T&gt;</span></p><s=
pan style=3D"font-family: courier new,monospace;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,monospace;">&nbsp;&nbsp;&nbsp; operator T() &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 =
new,monospace;">&nbsp;&nbsp;&nbsp; {</span></p><span style=3D"font-family: =
courier new,monospace;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return std::move=
(*this).Get&lt;T&gt;();</span></p><span style=3D"font-family: courier new,m=
onospace;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,monospace;">&nbsp;&nbsp;&nbsp; }</span></p><span style=3D"font-family: =
courier new,monospace;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,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 =
new,monospace;">&nbsp;&nbsp;&nbsp; template &lt;typename T&gt;</span></p><s=
pan style=3D"font-family: courier new,monospace;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,monospace;">&nbsp;&nbsp;&nbsp; T</span></p><span style=3D"font-family: =
courier new,monospace;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,monospace;">&nbsp;&nbsp;&nbsp; GetWithStuff() const &amp;</span></p><sp=
an style=3D"font-family: courier new,monospace;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,monospace;">&nbsp;&nbsp;&nbsp; {</span></p><span style=3D"font-family: =
courier new,monospace;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,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=
,monospace;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,monospace;">&nbsp;&nbsp;&nbsp; }</span></p><span style=3D"font-family: =
courier new,monospace;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,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 =
new,monospace;">&nbsp;&nbsp;&nbsp; template &lt;typename T&gt;</span></p><s=
pan style=3D"font-family: courier new,monospace;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,monospace;">&nbsp;&nbsp;&nbsp; T</span></p><span style=3D"font-family: =
courier new,monospace;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,monospace;">&nbsp;&nbsp;&nbsp; GetWithStuff() &amp;&amp;</span></p><spa=
n style=3D"font-family: courier new,monospace;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,monospace;">&nbsp;&nbsp;&nbsp; {</span></p><span style=3D"font-family: =
courier new,monospace;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;	return std::move=
(*this).Get&lt;T&gt;()
+ Stuff&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 =
new,monospace;">&nbsp;&nbsp;&nbsp; }</span></p><span style=3D"font-family: =
courier new,monospace;">
</span><span style=3D"font-family: courier new,monospace;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,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,mon=
ospace;">template &lt;this ThisType, 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 =
new,monospace;">T</span></p><span style=3D"font-family: courier new,monospa=
ce;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,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,mono=
space;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,monospace;">{</span></p><span style=3D"font-family: courier new,monospa=
ce;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,monospace;">&nbsp;&nbsp;&nbsp; return
std::forward&lt;ThisType&gt;(*this).Get&lt;T&gt;() + Stuff&lt;T&gt;();</spa=
n></p><span style=3D"font-family: courier new,monospace;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,monospace;">}</span></p><span style=3D"font-family: courier new,monospa=
ce;">
</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,mon=
ospace;">template &lt;this ThisType, 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 =
new,monospace;">T</span></p><span style=3D"font-family: courier new,monospa=
ce;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,monospace;">GetWithStuff() const ThisType &amp;</span></p><span style=
=3D"font-family: courier new,monospace;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,monospace;">{</span></p><span style=3D"font-family: courier new,monospa=
ce;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,monospace;">&nbsp;&nbsp;&nbsp; return
std::forward&lt;ThisType&gt;(*this).Get&lt;T&gt;() + Stuff&lt;T&gt;();</spa=
n></p><span style=3D"font-family: courier new,monospace;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,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,mon=
ospace;">template &lt;this ThisType, 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 =
new,monospace;">T</span></p><span style=3D"font-family: courier new,monospa=
ce;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,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 =
new,monospace;">{</span></p><span style=3D"font-family: courier new,monospa=
ce;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,monospace;">&nbsp;&nbsp;&nbsp; return
std::forward&lt;ThisType&gt;(*this).Get&lt;T&gt;() + Stuff&lt;T&gt;();</spa=
n></p><span style=3D"font-family: courier new,monospace;">
</span><p style=3D"margin-bottom: 0in"><span style=3D"font-family: courier =
new,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: 0i=
n"><br></p><p style=3D"margin-bottom: 0in">Best regards,</p><p style=3D"mar=
gin-bottom: 0in">Artyom<br></p></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_766_28935819.1377937554942--

.
