220 40974 <467a0621-ed78-4a96-b8f2-3485e059d840@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:41:04 -0800 (PST)
Lines: 449
Approved: news@gmane.org
Message-ID: <467a0621-ed78-4a96-b8f2-3485e059d840@isocpp.org>
References: <eeb29435-11b6-424e-8434-c0aeef0977f1@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_1658_1845307955.1541990464656"
X-Trace: blaine.gmane.org 1541990341 25505 195.159.176.226 (12 Nov 2018 02:39:01 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Mon, 12 Nov 2018 02:39:01 +0000 (UTC)
Cc: tecoberg@gmail.com
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBCFJBV63SUOBBQOQUPPQKGQE6CSUFRI@isocpp.org Mon Nov 12 03:38:56 2018
Return-path: <std-proposals+bncBCFJBV63SUOBBQOQUPPQKGQE6CSUFRI@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-yw1-f72.google.com ([209.85.161.72])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBCFJBV63SUOBBQOQUPPQKGQE6CSUFRI@isocpp.org>)
	id 1gM27s-0006Vd-Cc
	for gclcip-std-proposals@m.gmane.org; Mon, 12 Nov 2018 03:38:56 +0100
Original-Received: by mail-yw1-f72.google.com with SMTP id e62-v6sf7237089ywf.21
        for <gclcip-std-proposals@m.gmane.org>; Sun, 11 Nov 2018 18:41:07 -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=V6wPubtzCqDZTE/b+B9+Ssl5xcpq/7qn8fN+ObJkLKs=;
        b=m6Py2fbvu3KF9EjzGDBUsB7AvZbv88vOIRjaQfjdDuhU9cc4HMr+mqq7QriLcYv+Rk
         k4k6hDRWEuUwjdWQMK8J+5Mipzr7wZ746JOek1JeudnnJHd6N4gVXg3Up70ovo2+O5FE
         cITSi6xgejvdWU4HX9Rh2v6bzE+6G8TZo4lePbN88N7pGu0qjm5PD8lIlRexoNXzb3OS
         zTBEcB4nlLTtPZ2dZHe9/I18KZ8mxMtlEgMgSGiKdP8z0OlNhR9yK69Osfw79jUcR+74
         7kYyEe+Tujnd1hCB11pRTvcyEkyE6jOmszyYSS1Vy3j9hE7ZxaO+UX2i/S5cXrkwptqO
         FaTQ==
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=V6wPubtzCqDZTE/b+B9+Ssl5xcpq/7qn8fN+ObJkLKs=;
        b=NSq6pTiJ85MLvimxYANk8GZkQRe9vaYpBQz8Ko2+L3GQ8ebkJIojo0JFofDFzZMSFX
         uqSJjv+pFg7cXwRD4IqE+sJYWgByH3UOmX9qfWt+eBY6BVlkorCFmRHT2i837DfapB4D
         JERBrUS7ZuTxwiBLQk3ZkRysFjT5UISwj7h/6KW+FnNG1WEuznzpdKNdr5yt6dWgpvIG
         XSeHeNOOWgyvEawE37NrCQAjXhtd97PDMr5xMxr9VjzqF2eSEy/dogYrTaRdDihf7fb1
         3kXTRtYXLeKEkk7NtZ+Nnkkk7CvWTDyL7KnrMiQMzMKzov1HOHQjUBwRYDO+BnxarBTK
         haWA==
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=V6wPubtzCqDZTE/b+B9+Ssl5xcpq/7qn8fN+ObJkLKs=;
        b=eXBN5fSRSrwGuMWfIWzyQRs6syUS6bFCvk0cZvVl3JquIGjF1L2y/HlUVIj9n9mNMn
         hL86ECV8XJCpX9h8y0sVRu7/w4AwxHzsA3O6hJp2H91vr7TlhP0a39Op2WWmi4Wyi6PB
         zJuI8fF5QQxO9M8rsfrw/bnYFQjihsUWVN7jimEzR1D0mXB2MLaiRnIK03zG9sVmY9Ku
         yW07HHblGMjbkBwSzzxDs8Z6JEibxarrPEZvEcpr4jGOHk5VowSJ0eQAP3oklcLsJeOA
         ZhXr975oy/uWw/VQECTOT0GSwqXAq8hW8cSzEGYXN3Wj5aAAeWrGnPQj6eBvA0Oje6So
         Kv0w==
X-Gm-Message-State: AGRZ1gLKltW/jafR5jtPADk1rsOz93RvKRYu0tiw/xXeMk4Ln/i9pBb4
	U8r+cq89gb6YChnbbhbRwcgg+w==
X-Google-Smtp-Source: AJdET5eY9DeVI0Ixve1/7if1eclXOxCSBHdV4QiDPKxFpZT/315UffFDDekbm+e90tJiMA8UC5EpRw==
X-Received: by 2002:a81:58c2:: with SMTP id m185-v6mr9193975ywb.11.1541990466414;
        Sun, 11 Nov 2018 18:41:06 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 2002:a25:180b:: with SMTP id 11-v6ls126389yby.11.gmail; Sun, 11
 Nov 2018 18:41:05 -0800 (PST)
X-Received: by 2002:a25:afcd:: with SMTP id d13-v6mr183494ybj.2.1541990465215;
        Sun, 11 Nov 2018 18:41:05 -0800 (PST)
In-Reply-To: <eeb29435-11b6-424e-8434-c0aeef0977f1@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:40974
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/40974>

------=_Part_1658_1845307955.1541990464656
Content-Type: multipart/alternative; 
	boundary="----=_Part_1659_1014403419.1541990464657"

------=_Part_1659_1014403419.1541990464657
Content-Type: text/plain; charset="UTF-8"

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/467a0621-ed78-4a96-b8f2-3485e059d840%40isocpp.org.

------=_Part_1659_1014403419.1541990464657
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Suppose you had a template function recursive_arrow_f=
unc(p) that recursively applies operator-&gt; on p, as p.operator-&gt;().op=
erator-&gt;().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_arr=
ow_func(p)-&gt;FuncMember();<br></div><div><br></div><div>Even if p was a p=
ointer to pointer to pointer.<br><br>you could use this function to create =
one of several possible syntaxes, using a keyword, say &quot;arrows&quot;:<=
br><br><div>arrows(p)-&gt;FuncMember();</div><div>arrows[p]-&gt;FuncMember(=
);</div><div>arrows{p}-&gt;FuncMember();</div><div>arrows--(p)-&gt;FuncMemb=
er();</div></div><div><div>arrows--[p]-&gt;FuncMember();</div></div><div><d=
iv><div>arrows(p).FuncMember();</div><div>arrows[p].FuncMember();</div><div=
>arrows{p}.FuncMember();</div><div>arrows--(p).FuncMember();</div></div><di=
v>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>cl=
ass my_ptr</div><div>{</div><div>private:</div><div><span style=3D"white-sp=
ace:pre">	</span>T* m;</div><div><br></div><div>public:</div><div><span sty=
le=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><span style=3D"white-sp=
ace:pre">	</span>T&amp; operator*() const</div><div><span style=3D"white-sp=
ace:pre">	</span>{</div><div><span style=3D"white-space:pre">		</span>retur=
n *m;</div><div><span style=3D"white-space:pre">	</span>}</div><div>};</div=
><div><br></div><div><br></div><div>void g_test_recursive_arrow()<br></div>=
<div>{</div><div><span style=3D"white-space:pre">	</span>using element_t =
=3D std::pair&lt; double, double &gt;;</div><div><span style=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">	</span>my_ptr&lt; my_pt=
r&lt; element_t &gt; &gt; mm =3D &amp;m;</div><div><span style=3D"white-spa=
ce:pre">	</span>assert(a.first =3D=3D arrows(mm)-&gt;first);</div><div><br>=
</div><div><span style=3D"white-space:pre">	</span>my_ptr&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(mmm)-&gt;first);</di=
v><div><br></div><div><br></div><div><span style=3D"white-space:pre">	</spa=
n>element_t* p =3D &amp;a;</div><div><span style=3D"white-space:pre">	</spa=
n>assert(a.first =3D=3D arrows(p)-&gt;first);</div><div><br></div><div><spa=
n style=3D"white-space:pre">	</span>element_t** pp =3D &amp;p;</div><div><s=
pan style=3D"white-space:pre">	</span>assert(a.first =3D=3D arrows(pp)-&gt;=
first);</div><div><br></div><div><span style=3D"white-space:pre">	</span>el=
ement_t*** ppp =3D &amp;pp;</div><div><span style=3D"white-space:pre">	</sp=
an>assert(a.first =3D=3D arrows(ppp)-&gt;first);</div><div><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-space:pre">	</span>asse=
rt(a.first =3D=3D arrows(pm)-&gt;first);</div><div><br></div><div><span sty=
le=3D"white-space:pre">	</span>my_ptr&lt; element_t* &gt; mp =3D &amp;p;</d=
iv><div><span style=3D"white-space:pre">	</span>assert(a.first =3D=3D arrow=
s(mp)-&gt;first);</div><div><br></div><div><br></div><div><span style=3D"wh=
ite-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">	</span>assert(a.first =
=3D=3D arrows(mpm)-&gt;first);</div><div><br></div><div><span style=3D"whit=
e-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 implementation.<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 with operator-&gt; mus=
t has operator* to be usable.<br><br><br></div><div><div>namespace recursiv=
e_dereferencing {</div><div><span style=3D"white-space:pre">	</span>namespa=
ce detail {</div><div><br></div><div><br></div><div><span style=3D"white-sp=
ace:pre">		</span>template &lt;typename T&gt;</div><div><span style=3D"whit=
e-space:pre">		</span>class has_arrow</div><div><span style=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;::value;</div><d=
iv><span style=3D"white-space:pre">		</span>};</div><div><br></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_a=
rrow_result_impl;</div><div><br></div><div><span style=3D"white-space:pre">=
		</span>template&lt; typename T, bool &gt;</div><div><span style=3D"white-=
space:pre">		</span>class recursive_arrow_result_impl2</div><div><span styl=
e=3D"white-space:pre">		</span>{</div><div><span style=3D"white-space:pre">=
		</span>public: using type =3D typename recursive_arrow_result_impl&lt; st=
d::invoke_result_t&lt; decltype(&amp;(T::operator-&gt;)), T &gt; &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_r=
esult_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 ty=
pe =3D T &amp; ;</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 re=
cursive_arrow_result_impl</div><div><span style=3D"white-space:pre">		</spa=
n>{</div><div><span style=3D"white-space:pre">		</span>public: using type =
=3D typename recursive_arrow_result_impl2&lt;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; typena=
me T &gt;</div><div><span style=3D"white-space:pre">		</span>class recursiv=
e_arrow_result_impl&lt;T*&gt;</div><div><span style=3D"white-space:pre">		<=
/span>{</div><div><span style=3D"white-space:pre">		</span>public: using ty=
pe =3D typename recursive_arrow_result_impl&lt; T &gt;::type;</div><div><sp=
an style=3D"white-space:pre">		</span>};</div><div><br></div><div><span sty=
le=3D"white-space:pre">		</span>template&lt; typename T &gt;</div><div><spa=
n style=3D"white-space:pre">		</span>class recursive_arrow_result_impl&lt;T=
&amp;&gt;</div><div><span style=3D"white-space:pre">		</span>{</div><div><s=
pan style=3D"white-space:pre">		</span>public: using type =3D typename recu=
rsive_arrow_result_impl&lt; T &gt;::type;</div><div><span style=3D"white-sp=
ace:pre">		</span>};</div><div><br></div><div><span style=3D"white-space:pr=
e">		</span>template&lt; typename T &gt;</div><div><span style=3D"white-spa=
ce:pre">		</span>class recursive_arrow_result_impl&lt;T*&amp;&gt;</div><div=
><span style=3D"white-space:pre">		</span>{</div><div><span style=3D"white-=
space:pre">		</span>public: using 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>templat=
e&lt; typename T &gt;</div><div><span style=3D"white-space:pre">		</span>us=
ing recursive_arrow_result_impl_t =3D typename recursive_arrow_result_impl&=
lt;T&gt;::type;</div><div><br></div><div><br></div><div><span style=3D"whit=
e-space:pre">		</span>template&lt; typename T &gt;</div><div><span style=3D=
"white-space:pre">		</span>recursive_arrow_result_impl_t&lt;T&gt;</div><div=
><span style=3D"white-space:pre">			</span>recursive_arrow_impl(T&amp;&amp;=
 r</div><div><span style=3D"white-space:pre">				</span>, typename std::ena=
ble_if&lt; has_arrow&lt; 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::forward&lt;T&gt;(r).operator-&gt;());</div><div>=
<span style=3D"white-space:pre">		</span>}</div><div><br></div><div><span s=
tyle=3D"white-space:pre">		</span>template&lt; typename T &gt;</div><div><s=
pan style=3D"white-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_arrow&lt; T &gt;::value &gt;::type* =3D NULL</div><div><span s=
tyle=3D"white-space:pre">		</span>)</div><div><span style=3D"white-space:pr=
e">		</span>{</div><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_im=
pl_t&lt;T*&gt;</div><div><span style=3D"white-space:pre">			</span>recursiv=
e_arrow_impl(T* r)</div><div><span style=3D"white-space:pre">		</span>{</di=
v><div><span style=3D"white-space:pre">			</span>return recursive_arrow_imp=
l(*r);</div><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; typename T &gt;</div><div><span style=3D"white-space:pre">		</span>usin=
g recursive_arrow_result_t =3D std::remove_reference_t&lt; recursive_arrow_=
result_impl_t&lt; T &gt; &gt;*;</div><div><br></div><div><span style=3D"whi=
te-space:pre">		</span>template&lt; typename T &gt;</div><div><span style=
=3D"white-space:pre">		</span>recursive_arrow_result_t&lt;T&gt; recursive_a=
rrow(T&amp;&amp; r)</div><div><span style=3D"white-space:pre">		</span>{</d=
iv><div><span style=3D"white-space:pre">			</span>return std::addressof(rec=
ursive_arrow_impl(std::forward&lt;T&gt;(r)));</div><div><span style=3D"whit=
e-space:pre">		</span>}</div><div><br></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>detail::recursive_arrow_result_t&lt;T&gt; recursive_arrow(T&amp;&=
amp; r)</div><div><span style=3D"white-space:pre">	</span>{</div><div><span=
 style=3D"white-space:pre">		</span>return detail::recursive_arrow(std::for=
ward&lt;T&gt;(r));</div><div><span style=3D"white-space:pre">	</span>}</div=
><div><br></div><div>}</div><div><br></div><div><br></div><div>template&lt;=
 typename T &gt;</div><div>std::invoke_result_t&lt; decltype(&amp;recursive=
_dereferencing::recursive_arrow&lt;T&gt;), T&amp;&amp; &gt;</div><div>recur=
sive_arrow_func(T&amp;&amp; r)</div><div>{</div><div><span style=3D"white-s=
pace:pre">	</span>return recursive_dereferencing::recursive_arrow(std::forw=
ard&lt;T&gt;(r));</div><div>}</div><div><br></div><br></div><div><br></div>=
<br>On Monday, 29 October 2018 09:00:15 UTC+2, teco...@gmail.com  wrote:<bl=
ockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border=
-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>Hi,=C2=A0</=
div><div><br></div><div>If we have a container of unitque_ptr/shared_ptr ob=
jects, to reference to them we can usethe follow notations:</div><div><br><=
/div><div><b>p-&gt;FuncMember();</b>=C2=A0=C2=A0 //Same as <b>(*p).FuncMemb=
er();</b></div><div><br></div><div>but, some times I need to create a point=
er to this pointer and I use to write the follow notation:</div><div><br></=
div><div><b>(*p2p)-&gt;FuncMember();</b></div><div><br></div><div>I think i=
t will be a good idea if c++ could have a notation to this situations like:=
</div><div><br></div><div><b>p2p=3D&gt;FuncMember() </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></div><div><b>p2p:&gt;FuncMember()=
</b><br></div><div><br></div><div>What do you think?</div><div><br></div><d=
iv>I hope I helped in some way.<br></div><div><br></div><div><br></div></di=
v></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/467a0621-ed78-4a96-b8f2-3485e059d840%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/467a0621-ed78-4a96-b8f2-3485e059d840=
%40isocpp.org</a>.<br />

------=_Part_1659_1014403419.1541990464657--

------=_Part_1658_1845307955.1541990464656--

.
