220 40975 <f8cda263-6bfd-477e-b4eb-ad73f6c7e915@isocpp.org> article
Path: news.gmane.org!.POSTED!not-for-mail
From: Itaj Sherman <itajsherman@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Pointer to pointer representation
Date: Sun, 11 Nov 2018 18:53:12 -0800 (PST)
Lines: 469
Approved: news@gmane.org
Message-ID: <f8cda263-6bfd-477e-b4eb-ad73f6c7e915@isocpp.org>
References: <eeb29435-11b6-424e-8434-c0aeef0977f1@isocpp.org>
 <467a0621-ed78-4a96-b8f2-3485e059d840@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_1724_1356553565.1541991192228"
X-Trace: blaine.gmane.org 1541991072 28237 195.159.176.226 (12 Nov 2018 02:51:12 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Mon, 12 Nov 2018 02:51:12 +0000 (UTC)
Cc: tecoberg@gmail.com
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBCFJBV63SUOBBGOWUPPQKGQE4KRASQY@isocpp.org Mon Nov 12 03:51:07 2018
Return-path: <std-proposals+bncBCFJBV63SUOBBGOWUPPQKGQE4KRASQY@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-yw1-f69.google.com ([209.85.161.69])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBCFJBV63SUOBBGOWUPPQKGQE4KRASQY@isocpp.org>)
	id 1gM2Jb-00073y-FS
	for gclcip-std-proposals@m.gmane.org; Mon, 12 Nov 2018 03:51:03 +0100
Original-Received: by mail-yw1-f69.google.com with SMTP id w185-v6sf1582612ywa.2
        for <gclcip-std-proposals@m.gmane.org>; Sun, 11 Nov 2018 18:53:14 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=date:from:to:cc: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;
        bh=NTZr4/OhB8EH9KknmNmlHEkW1E8cA70S2UWvAJj8MgY=;
        b=zBMSjemzu3mBEjvK3IUT3wGGpCd1QUmEiPuXoVpzVFMuTOXMoCEIoTX7gykcf+vao7
         Flh3t7pdEm4RMb/lunT+0XM7ThiCUK4831wfgG52H5SwerNjjmMFmpWEmSJDDLfFqA3m
         LGLSYAX5b+7GupUvyJa7IzSZU7vSEix8fXFcf0S6kk4WQt3U9MIE93J4CTSPsndimsBJ
         Mru6Ne1Am9SAyBoS2VXWn4ijnGgB329eDbC1juOa4lIIGfIkwk+Nrn29jk/g39sJQXrO
         NJxC8ge/44E7I43WKH9UKm7PsSwzIdp/9prEet4xAWm7fTIkJfJtHeNeKhw4Jyybev66
         b5xA==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20161025;
        h=date:from:to:cc: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;
        bh=NTZr4/OhB8EH9KknmNmlHEkW1E8cA70S2UWvAJj8MgY=;
        b=O8N9CRpKArCoh31E3ECQPcittIIwLI6A6JxuYkJXVJtEgRpu5a1bHq1rCcGMcFeYsA
         nhWd4W4sZK0/o62248f9shKrivws+DiCNWs+huWpXAzDeyFkglJit7pIR0EF/s8a4Fsy
         lmlW3ckTtLqnld7Hj6txgKOWHO1MdjU8JCTCkLIW9VU36l9LuJePL+zPVM+QChdjJvJE
         LNcK83cw662cynfBzcVuDFnbJ8PUs3I+5deHLLe7ZY9MG4b6SWeqQqp23X/4B2eau4wx
         6EukLxZPPqPnLmBnddMOT4U8Mt3VesulYzAL0T55ja/k3KveYPULGxDsP7/iN03jalNt
         Zguw==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20161025;
        h=x-gm-message-state:date:from:to:cc:message-id:in-reply-to
         :references:subject:mime-version:x-original-sender:reply-to
         :precedence:mailing-list:list-id:x-spam-checked-in-group:list-post
         :list-help:list-archive:list-subscribe:list-unsubscribe;
        bh=NTZr4/OhB8EH9KknmNmlHEkW1E8cA70S2UWvAJj8MgY=;
        b=EIAdjbSPPLoyeVCAxB4OtoOp6zRSPI0JytpeX6v1KZm7YI46iBdXUIiBQGkGosLBE0
         ITFuMByIB24rubB14qh9T1e9T7pZ5s9cGUNyQborI5SWCSwPukA8eZdeEmFW4Mt8qWkU
         XfNt2JcDP3iT89uLS7GSSj8VRJm0VTuna4MDs7Df0VXqt4g+rXS6R3iv5V1hhoJ6XzLk
         ERqgIWs/J9CJD4C9InsCjH96LWG3gnKkuoONARand0DZ7QHm1/B6uPgX13tla8JmzwK/
         k3wRgY8l9ZT2Yd0adnzoH4sTZScW5qp5ssveuUT7aTRCliS3pT5HkFFV3Y4jxnGmC6gW
         9sig==
X-Gm-Message-State: AGRZ1gIb7AVOog7GzTYxozowjb1N0sIy2MACnzTQoYJTKig8HXP09Rm0
	Oj5YCKThHaxawV5wajzJ+Qjexw==
X-Google-Smtp-Source: AJdET5dUicW3ySg9SUVTOkttsavAt8AirhB0VtvDjrPcbFn3lWS4qDClRORb2QoJ1zzLzewcIDva8A==
X-Received: by 2002:a25:7805:: with SMTP id t5-v6mr3876082ybc.41.1541991193782;
        Sun, 11 Nov 2018 18:53:13 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 2002:a5b:446:: with SMTP id s6-v6ls3056606ybp.3.gmail; Sun, 11
 Nov 2018 18:53:12 -0800 (PST)
X-Received: by 2002:a25:d60d:: with SMTP id n13-v6mr179036ybg.7.1541991192715;
        Sun, 11 Nov 2018 18:53:12 -0800 (PST)
In-Reply-To: <467a0621-ed78-4a96-b8f2-3485e059d840@isocpp.org>
X-Original-Sender: itajsherman@gmail.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Spam-Checked-In-Group: std-proposals@isocpp.org
X-Google-Group-Id: 399137483710
List-Post: <https://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <https://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <https://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>,
 <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:40975
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/40975>

------=_Part_1724_1356553565.1541991192228
Content-Type: multipart/alternative; 
	boundary="----=_Part_1725_850149995.1541991192229"

------=_Part_1725_850149995.1541991192229
Content-Type: text/plain; charset="UTF-8"

....But I wholeheartedly recommend you don't do stuff like that.
Dereferencing is an important construction in the logic of your code. The 
different between none, one or two dereferencing might be very meaningful 
to a reader of the code - these differences should be readily explicit.
It might only make sense in extremely specialized situations, and I'd 
recommend that it you ever use such function make sure it only compiles for 
classes of a specialized concept.

On Monday, 12 November 2018 04:41:04 UTC+2, Itaj Sherman wrote:
>
> Suppose you had a template function recursive_arrow_func(p) that 
> recursively applies operator-> on p, as 
> p.operator->().operator->().operator->() until it returns a pointer to an 
> object type that has no operator->
>
> Then you could use it as:
> recursive_arrow_func(p)->FuncMember();
>
> Even if p was a pointer to pointer to pointer.
>
> you could use this function to create one of several possible syntaxes, 
> using a keyword, say "arrows":
>
> arrows(p)->FuncMember();
> arrows[p]->FuncMember();
> arrows{p}->FuncMember();
> arrows--(p)->FuncMember();
> arrows--[p]->FuncMember();
> arrows(p).FuncMember();
> arrows[p].FuncMember();
> arrows{p}.FuncMember();
> arrows--(p).FuncMember();
> arrows--[p].FuncMember();
>
> It could even do stuff like this:
>
> template< typename T >
> class my_ptr
> {
> private:
> T* m;
>
> public:
> my_ptr(T* r) : m(r) {}
>
> public:
> T* operator->() const
> {
> return m;
> }
>
> T& operator*() const
> {
> return *m;
> }
> };
>
>
> void g_test_recursive_arrow()
> {
> using element_t = std::pair< double, double >;
> element_t a = { 1.5, 2.5 };
>
> my_ptr< element_t > m = &a;
> assert(a.first == arrows(m)->first);
>
> my_ptr< my_ptr< element_t > > mm = &m;
> assert(a.first == arrows(mm)->first);
>
> my_ptr< my_ptr< my_ptr< element_t > > > mmm = &mm;
> assert(a.first == arrows(mmm)->first);
>
>
> element_t* p = &a;
> assert(a.first == arrows(p)->first);
>
> element_t** pp = &p;
> assert(a.first == arrows(pp)->first);
>
> element_t*** ppp = &pp;
> assert(a.first == arrows(ppp)->first);
>
>
> my_ptr< element_t >* pm = &m;
> assert(a.first == arrows(pm)->first);
>
> my_ptr< element_t* > mp = &p;
> assert(a.first == arrows(mp)->first);
>
>
> my_ptr< my_ptr< element_t >* > mpm = &pm;
> assert(a.first == arrows(mpm)->first);
>
> my_ptr< element_t* >* pmp = &mp;
> assert(a.first == arrows(pmp)->first);
>
> }
>
>
>
> Here's a possible implementation.
> I needed a traits 'has_arrow<T>' but I couldn't find it in boost, so I 
> used boost::has_dereference.
> So classes with operator-> must has operator* to be usable.
>
>
> namespace recursive_dereferencing {
> namespace detail {
>
>
> template <typename T>
> class has_arrow
> {
> public: static const bool value = boost::has_dereference<T>::value;
> };
>
>
> template< typename T >
> class recursive_arrow_result_impl;
>
> template< typename T, bool >
> class recursive_arrow_result_impl2
> {
> public: using type = typename recursive_arrow_result_impl< 
> std::invoke_result_t< decltype(&(T::operator->)), T > >::type;
> };
>
> template< typename T >
> class recursive_arrow_result_impl2< T, false >
> {
> public: using type = T & ;
> };
>
> template< typename T >
> class recursive_arrow_result_impl
> {
> public: using type = typename recursive_arrow_result_impl2<T, 
> has_arrow<T>::value >::type;
> };
>
> template< typename T >
> class recursive_arrow_result_impl<T*>
> {
> public: using type = typename recursive_arrow_result_impl< T >::type;
> };
>
> template< typename T >
> class recursive_arrow_result_impl<T&>
> {
> public: using type = typename recursive_arrow_result_impl< T >::type;
> };
>
> template< typename T >
> class recursive_arrow_result_impl<T*&>
> {
> public: using type = typename recursive_arrow_result_impl< T >::type;
> };
>
> template< typename T >
> using recursive_arrow_result_impl_t = typename 
> recursive_arrow_result_impl<T>::type;
>
>
> template< typename T >
> recursive_arrow_result_impl_t<T>
> recursive_arrow_impl(T&& r
> , typename std::enable_if< has_arrow< T >::value >::type* = NULL
> )
> {
> return recursive_arrow_impl(std::forward<T>(r).operator->());
> }
>
> template< typename T >
> T& recursive_arrow_impl(T& r
> , typename std::enable_if< !has_arrow< T >::value >::type* = NULL
> )
> {
> return r;
> }
>
> template< typename T >
> recursive_arrow_result_impl_t<T*>
> recursive_arrow_impl(T* r)
> {
> return recursive_arrow_impl(*r);
> }
>
>
> template< typename T >
> using recursive_arrow_result_t = std::remove_reference_t< 
> recursive_arrow_result_impl_t< T > >*;
>
> template< typename T >
> recursive_arrow_result_t<T> recursive_arrow(T&& r)
> {
> return std::addressof(recursive_arrow_impl(std::forward<T>(r)));
> }
>
> }
>
> template< typename T >
> detail::recursive_arrow_result_t<T> recursive_arrow(T&& r)
> {
> return detail::recursive_arrow(std::forward<T>(r));
> }
>
> }
>
>
> template< typename T >
> std::invoke_result_t< 
> decltype(&recursive_dereferencing::recursive_arrow<T>), T&& >
> recursive_arrow_func(T&& r)
> {
> return recursive_dereferencing::recursive_arrow(std::forward<T>(r));
> }
>
>
>
>
> On Monday, 29 October 2018 09:00:15 UTC+2, teco...@gmail.com wrote:
>>
>> Hi, 
>>
>> If we have a container of unitque_ptr/shared_ptr objects, to reference to 
>> them we can usethe follow notations:
>>
>> *p->FuncMember();*   //Same as *(*p).FuncMember();*
>>
>> but, some times I need to create a pointer to this pointer and I use to 
>> write the follow notation:
>>
>> *(*p2p)->FuncMember();*
>>
>> I think it will be a good idea if c++ could have a notation to this 
>> situations like:
>>
>> *p2p=>FuncMember() *//or
>>
>> *p2p+>FuncMember()* //or
>>
>> *p2p#>FuncMember()* //or
>>
>> *p2p:>FuncMember()*
>>
>> What do you think?
>>
>> I hope I helped in some way.
>>
>>
>>

-- 
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/f8cda263-6bfd-477e-b4eb-ad73f6c7e915%40isocpp.org.

------=_Part_1725_850149995.1541991192229
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">...But I wholeheartedly recommend you don&#39;t do stuff l=
ike that.<br>Dereferencing is an important construction in the logic of you=
r code. The different between none, one or two dereferencing might be very =
meaningful to a reader of the code - these differences should be readily ex=
plicit.<br>It might only make sense in extremely specialized situations, an=
d I&#39;d recommend that it you ever use such function make sure it only co=
mpiles for classes of a specialized concept.<br><br>On Monday, 12 November =
2018 04:41:04 UTC+2, Itaj Sherman  wrote:<blockquote class=3D"gmail_quote" =
style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-l=
eft: 1ex;"><div dir=3D"ltr"><div>Suppose you had a template function recurs=
ive_arrow_func(p) that recursively applies operator-&gt; on p, as p.operato=
r-&gt;().operator-&gt;().<wbr>operator-&gt;() until it returns a pointer to=
 an object type that has no operator-&gt;<br><br>Then you could use it as:<=
br>recursive_arrow_func(p)-&gt;<wbr>FuncMember();<br></div><div><br></div><=
div>Even if p was a pointer to pointer to pointer.<br><br>you could use thi=
s function to create one of several possible syntaxes, using a keyword, say=
 &quot;arrows&quot;:<br><br><div>arrows(p)-&gt;FuncMember();</div><div>arro=
ws[p]-&gt;FuncMember();</div><div>arrows{p}-&gt;FuncMember();</div><div>arr=
ows--(p)-&gt;FuncMember();</div></div><div><div>arrows--[p]-&gt;FuncMember(=
);</div></div><div><div><div>arrows(p).FuncMember();</div><div>arrows[p].Fu=
ncMember();</div><div>arrows{p}.FuncMember();</div><div>arrows--(p).FuncMem=
ber();</div></div><div>arrows--[p].FuncMember();</div></div><div><br></div>=
<div>It could even do stuff like this:<br><br>template&lt; typename T &gt;<=
br></div><div><div>class my_ptr</div><div>{</div><div>private:</div><div><s=
pan style=3D"white-space:pre">	</span>T* m;</div><div><br></div><div>public=
:</div><div><span style=3D"white-space:pre">	</span>my_ptr(T* r) : m(r) {}<=
/div><div><br></div><div>public:</div><div><span style=3D"white-space:pre">=
	</span>T* operator-&gt;() const</div><div><span style=3D"white-space:pre">=
	</span>{</div><div><span style=3D"white-space:pre">		</span>return m;</div=
><div><span style=3D"white-space:pre">	</span>}</div><div><br></div><div><s=
pan style=3D"white-space:pre">	</span>T&amp; operator*() const</div><div><s=
pan style=3D"white-space:pre">	</span>{</div><div><span style=3D"white-spac=
e:pre">		</span>return *m;</div><div><span style=3D"white-space:pre">	</spa=
n>}</div><div>};</div><div><br></div><div><br></div><div>void g_test_recurs=
ive_arrow()<br></div><div>{</div><div><span style=3D"white-space:pre">	</sp=
an>using element_t =3D std::pair&lt; double, double &gt;;</div><div><span s=
tyle=3D"white-space:pre">	</span></div><div><span style=3D"white-space:pre"=
>	</span>element_t a =3D { 1.5, 2.5 };</div><div><br></div><div><span style=
=3D"white-space:pre">	</span>my_ptr&lt; element_t &gt; m =3D &amp;a;</div><=
div><span style=3D"white-space:pre">	</span>assert(a.first =3D=3D arrows(m)=
-&gt;first);</div><div><br></div><div><span style=3D"white-space:pre">	</sp=
an>my_ptr&lt; my_ptr&lt; element_t &gt; &gt; mm =3D &amp;m;</div><div><span=
 style=3D"white-space:pre">	</span>assert(a.first =3D=3D arrows(mm)-&gt;fir=
st);</div><div><br></div><div><span style=3D"white-space:pre">	</span>my_pt=
r&lt; my_ptr&lt; my_ptr&lt; element_t &gt; &gt; &gt; mmm =3D &amp;mm;</div>=
<div><span style=3D"white-space:pre">	</span>assert(a.first =3D=3D arrows(m=
mm)-&gt;first);</div><div><br></div><div><br></div><div><span style=3D"whit=
e-space:pre">	</span>element_t* p =3D &amp;a;</div><div><span style=3D"whit=
e-space:pre">	</span>assert(a.first =3D=3D arrows(p)-&gt;first);</div><div>=
<br></div><div><span style=3D"white-space:pre">	</span>element_t** pp =3D &=
amp;p;</div><div><span style=3D"white-space:pre">	</span>assert(a.first =3D=
=3D arrows(pp)-&gt;first);</div><div><br></div><div><span style=3D"white-sp=
ace:pre">	</span>element_t*** ppp =3D &amp;pp;</div><div><span style=3D"whi=
te-space:pre">	</span>assert(a.first =3D=3D arrows(ppp)-&gt;first);</div><d=
iv><br></div><div><br></div><div><span style=3D"white-space:pre">	</span>my=
_ptr&lt; element_t &gt;* pm =3D &amp;m;</div><div><span style=3D"white-spac=
e:pre">	</span>assert(a.first =3D=3D arrows(pm)-&gt;first);</div><div><br><=
/div><div><span style=3D"white-space:pre">	</span>my_ptr&lt; element_t* &gt=
; mp =3D &amp;p;</div><div><span style=3D"white-space:pre">	</span>assert(a=
..first =3D=3D arrows(mp)-&gt;first);</div><div><br></div><div><br></div><di=
v><span style=3D"white-space:pre">	</span>my_ptr&lt; my_ptr&lt; element_t &=
gt;* &gt; mpm =3D &amp;pm;</div><div><span style=3D"white-space:pre">	</spa=
n>assert(a.first =3D=3D arrows(mpm)-&gt;first);</div><div><br></div><div><s=
pan style=3D"white-space:pre">	</span>my_ptr&lt; element_t* &gt;* pmp =3D &=
amp;mp;</div><div><span style=3D"white-space:pre">	</span>assert(a.first =
=3D=3D arrows(pmp)-&gt;first);</div><div><br></div><div>}</div></div><div><=
br></div><div><br></div><div><br></div><div>Here&#39;s a possible implement=
ation.<br>I needed a traits &#39;has_arrow&lt;T&gt;&#39; but I couldn&#39;t=
 find it in boost, so I used=C2=A0boost::has_dereference.<br>So classes wit=
h operator-&gt; must has operator* to be usable.<br><br><br></div><div><div=
>namespace recursive_dereferencing {</div><div><span style=3D"white-space:p=
re">	</span>namespace detail {</div><div><br></div><div><br></div><div><spa=
n style=3D"white-space:pre">		</span>template &lt;typename T&gt;</div><div>=
<span style=3D"white-space:pre">		</span>class has_arrow</div><div><span st=
yle=3D"white-space:pre">		</span>{</div><div><span style=3D"white-space:pre=
">		</span>public: static const bool value =3D boost::has_dereference&lt;T&=
gt;::<wbr>value;</div><div><span style=3D"white-space:pre">		</span>};</div=
><div><br></div><div><br></div><div><span style=3D"white-space:pre">		</spa=
n>template&lt; typename T &gt;</div><div><span style=3D"white-space:pre">		=
</span>class recursive_arrow_result_impl;</div><div><br></div><div><span st=
yle=3D"white-space:pre">		</span>template&lt; typename T, bool &gt;</div><d=
iv><span style=3D"white-space:pre">		</span>class recursive_arrow_result_im=
pl2</div><div><span style=3D"white-space:pre">		</span>{</div><div><span st=
yle=3D"white-space:pre">		</span>public: using type =3D typename recursive_=
arrow_result_impl&lt; std::invoke_result_t&lt; decltype(&amp;(T::operator-&=
gt;)), T &gt; &gt;::type;</div><div><span style=3D"white-space:pre">		</spa=
n>};</div><div><br></div><div><span style=3D"white-space:pre">		</span>temp=
late&lt; typename T &gt;</div><div><span style=3D"white-space:pre">		</span=
>class recursive_arrow_result_impl2&lt; T, false &gt;</div><div><span style=
=3D"white-space:pre">		</span>{</div><div><span style=3D"white-space:pre">	=
	</span>public: using type =3D T &amp; ;</div><div><span style=3D"white-spa=
ce:pre">		</span>};</div><div><br></div><div><span style=3D"white-space:pre=
">		</span>template&lt; typename T &gt;</div><div><span style=3D"white-spac=
e:pre">		</span>class recursive_arrow_result_impl</div><div><span style=3D"=
white-space:pre">		</span>{</div><div><span style=3D"white-space:pre">		</s=
pan>public: using type =3D typename recursive_arrow_result_impl2&lt;<wbr>T,=
 has_arrow&lt;T&gt;::value &gt;::type;</div><div><span style=3D"white-space=
:pre">		</span>};</div><div><br></div><div><span style=3D"white-space:pre">=
		</span>template&lt; typename T &gt;</div><div><span style=3D"white-space:=
pre">		</span>class recursive_arrow_result_impl&lt;T*<wbr>&gt;</div><div><s=
pan style=3D"white-space:pre">		</span>{</div><div><span style=3D"white-spa=
ce:pre">		</span>public: using type =3D typename recursive_arrow_result_imp=
l&lt; T &gt;::type;</div><div><span style=3D"white-space:pre">		</span>};</=
div><div><br></div><div><span style=3D"white-space:pre">		</span>template&l=
t; typename T &gt;</div><div><span style=3D"white-space:pre">		</span>class=
 recursive_arrow_result_impl&lt;T&amp;<wbr>&gt;</div><div><span style=3D"wh=
ite-space:pre">		</span>{</div><div><span style=3D"white-space:pre">		</spa=
n>public: using type =3D typename recursive_arrow_result_impl&lt; T &gt;::t=
ype;</div><div><span style=3D"white-space:pre">		</span>};</div><div><br></=
div><div><span style=3D"white-space:pre">		</span>template&lt; typename T &=
gt;</div><div><span style=3D"white-space:pre">		</span>class recursive_arro=
w_result_impl&lt;T*<wbr>&amp;&gt;</div><div><span style=3D"white-space:pre"=
>		</span>{</div><div><span style=3D"white-space:pre">		</span>public: usin=
g type =3D typename recursive_arrow_result_impl&lt; T &gt;::type;</div><div=
><span style=3D"white-space:pre">		</span>};</div><div><br></div><div><span=
 style=3D"white-space:pre">		</span>template&lt; typename T &gt;</div><div>=
<span style=3D"white-space:pre">		</span>using recursive_arrow_result_impl_=
t =3D typename recursive_arrow_result_impl&lt;T&gt;<wbr>::type;</div><div><=
br></div><div><br></div><div><span style=3D"white-space:pre">		</span>templ=
ate&lt; typename T &gt;</div><div><span style=3D"white-space:pre">		</span>=
recursive_arrow_result_impl_t&lt;<wbr>T&gt;</div><div><span style=3D"white-=
space:pre">			</span>recursive_arrow_impl(T&amp;&amp; r</div><div><span sty=
le=3D"white-space:pre">				</span>, typename std::enable_if&lt; has_arrow&l=
t; T &gt;::value &gt;::type* =3D NULL</div><div><span style=3D"white-space:=
pre">			</span>)</div><div><span style=3D"white-space:pre">		</span>{</div>=
<div><span style=3D"white-space:pre">			</span>return recursive_arrow_impl(=
std::<wbr>forward&lt;T&gt;(r).operator-&gt;());</div><div><span style=3D"wh=
ite-space:pre">		</span>}</div><div><br></div><div><span style=3D"white-spa=
ce:pre">		</span>template&lt; typename T &gt;</div><div><span style=3D"whit=
e-space:pre">		</span>T&amp; recursive_arrow_impl(T&amp; r</div><div><span =
style=3D"white-space:pre">			</span>, typename std::enable_if&lt; !has_arro=
w&lt; T &gt;::value &gt;::type* =3D NULL</div><div><span style=3D"white-spa=
ce:pre">		</span>)</div><div><span style=3D"white-space:pre">		</span>{</di=
v><div><span style=3D"white-space:pre">			</span>return r;</div><div><span =
style=3D"white-space:pre">		</span>}</div><div><br></div><div><span style=
=3D"white-space:pre">		</span>template&lt; typename T &gt;</div><div><span =
style=3D"white-space:pre">		</span>recursive_arrow_result_impl_t&lt;<wbr>T*=
&gt;</div><div><span style=3D"white-space:pre">			</span>recursive_arrow_im=
pl(T* r)</div><div><span style=3D"white-space:pre">		</span>{</div><div><sp=
an style=3D"white-space:pre">			</span>return recursive_arrow_impl(*r);</di=
v><div><span style=3D"white-space:pre">		</span>}</div><div><br></div><div>=
<br></div><div><span style=3D"white-space:pre">		</span>template&lt; typena=
me T &gt;</div><div><span style=3D"white-space:pre">		</span>using recursiv=
e_arrow_result_t =3D std::remove_reference_t&lt; recursive_arrow_result_imp=
l_t&lt; T &gt; &gt;*;</div><div><br></div><div><span style=3D"white-space:p=
re">		</span>template&lt; typename T &gt;</div><div><span style=3D"white-sp=
ace:pre">		</span>recursive_arrow_result_t&lt;T&gt; recursive_arrow(T&amp;&=
amp; r)</div><div><span style=3D"white-space:pre">		</span>{</div><div><spa=
n style=3D"white-space:pre">			</span>return std::addressof(recursive_<wbr>=
arrow_impl(std::forward&lt;T&gt;(r))<wbr>);</div><div><span style=3D"white-=
space:pre">		</span>}</div><div><br></div><div><span style=3D"white-space:p=
re">	</span>}</div><div><br></div><div><span style=3D"white-space:pre">	</s=
pan>template&lt; typename T &gt;</div><div><span style=3D"white-space:pre">=
	</span>detail::recursive_arrow_<wbr>result_t&lt;T&gt; recursive_arrow(T&am=
p;&amp; r)</div><div><span style=3D"white-space:pre">	</span>{</div><div><s=
pan style=3D"white-space:pre">		</span>return detail::recursive_arrow(std::=
<wbr>forward&lt;T&gt;(r));</div><div><span style=3D"white-space:pre">	</spa=
n>}</div><div><br></div><div>}</div><div><br></div><div><br></div><div>temp=
late&lt; typename T &gt;</div><div>std::invoke_result_t&lt; decltype(&amp;r=
ecursive_<wbr>dereferencing::recursive_<wbr>arrow&lt;T&gt;), T&amp;&amp; &g=
t;</div><div>recursive_arrow_func(T&amp;&amp; r)</div><div>{</div><div><spa=
n style=3D"white-space:pre">	</span>return recursive_dereferencing::<wbr>re=
cursive_arrow(std::forward&lt;<wbr>T&gt;(r));</div><div>}</div><div><br></d=
iv><br></div><div><br></div><br>On Monday, 29 October 2018 09:00:15 UTC+2, =
<a>teco...@gmail.com</a>  wrote:<blockquote class=3D"gmail_quote" style=3D"=
margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><di=
v dir=3D"ltr"><div>Hi,=C2=A0</div><div><br></div><div>If we have a containe=
r of unitque_ptr/shared_ptr objects, to reference to them we can usethe fol=
low notations:</div><div><br></div><div><b>p-&gt;FuncMember();</b>=C2=A0=C2=
=A0 //Same as <b>(*p).FuncMember();</b></div><div><br></div><div>but, some =
times I need to create a pointer to this pointer and I use to write the fol=
low notation:</div><div><br></div><div><b>(*p2p)-&gt;FuncMember();</b></div=
><div><br></div><div>I think it will be a good idea if c++ could have a not=
ation to this situations like:</div><div><br></div><div><b>p2p=3D&gt;FuncMe=
mber() </b>//or</div><div><br></div><div><b>p2p+&gt;FuncMember()</b> //or</=
div><div><br></div><div><b>p2p#&gt;FuncMember()</b> //or</div><div><br></di=
v><div><b>p2p:&gt;FuncMember()</b><br></div><div><br></div><div>What do you=
 think?</div><div><br></div><div>I hope I helped in some way.<br></div><div=
><br></div><div><br></div></div></blockquote></div></blockquote></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/f8cda263-6bfd-477e-b4eb-ad73f6c7e915%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/f8cda263-6bfd-477e-b4eb-ad73f6c7e915=
%40isocpp.org</a>.<br />

------=_Part_1725_850149995.1541991192229--

------=_Part_1724_1356553565.1541991192228--

.
