Topic: safe_ref<T> proposal


Author: Fernando Pelliccioni <fpelliccioni@gmail.com>
Date: Thu, 13 Dec 2012 01:11:58 -0300
Raw View
--e89a8fb2058ebce85c04d0b41d13
Content-Type: text/plain; charset=ISO-8859-1

Hi all,

The motivation is to avoid code like the following...

//----------------------------------------------------------------------------
#include <iostream>
#include <string>

struct A
{
    void do_something( std::string s ) const
    {
        std::cout << "do something with " << s << " and " << i_ << "\n";
    }

    int i_ = 99;
};

// unsafe traditional code
struct Unsafe
{
    void set_ref( A& a )
    {
        a_ptr_ = std::addressof(a);
    }

    void use_ref( std::string s ) const
    {
        if (a_ptr_ != nullptr)
        {
            a_ptr_->do_something(s);
        }
    }

    void use_ref_2( std::string s ) const
    {
        //forgot to check for nullptr
        a_ptr_->do_something(s);
    }

    A* a_ptr_ = nullptr; //I can't use A& nor reference_wrapper<A>, need to
be nullable.
};

void f()
{
    A a;

    Unsafe unsafe;
    unsafe.use_ref( "hello" );              //null reference, do nothing,
hope!
    unsafe.set_ref(a);
    unsafe.use_ref( "hello world!" );       //not-null reference, Ok!

    Unsafe unsafe2;
    unsafe2.use_ref( "hello" );              //null reference, do nothing,
hope!
    unsafe2.use_ref_2( "hello" );            //null reference, Ops!
}
//----------------------------------------------------------------------------





The proposed solution:

//----------------------------------------------------------------------------
// Proposed (draft)
//----------------------------------------------------------------------------

template <typename T>
class safe_ref
{
public:
    typedef T type;

    explicit safe_ref()
        : t_( nullptr )
    {}

    explicit safe_ref(T& t)
        : t_( std::addressof(t) )
    {}

    template <typename Func>
    void use ( Func f ) const
    {
        if ( is_initialized() )
        {
            f( *t_ );
        }
    }

private:
    bool is_initialized() const
    {
        return t_ != nullptr;
    }


    T* t_;
};

template <typename T>
inline safe_ref<T> const ref(T& t)
{
    return safe_ref<T>(t);
}

template <typename T>
inline safe_ref<T const> const cref(T const& t)
{
    return safe_ref<T const>(t);
}


//----------------------------------------------------------------------------
// Usage
//----------------------------------------------------------------------------

#include <iostream>
#include <string>

struct A
{
    void do_something( std::string s ) const
    {
        std::cout << "A::do_something with " << s << " and " << i_ << "\n";
    }

    int i_ = 99;
};

struct Safe
{
    void set_ref( A& a )
    {
        a_ref_ = ref(a);
    }

    void use_ref( std::string s ) const
    {
        a_ref_.use( [&s] ( A& a ) {
            a.do_something(s);
        });
    }

    safe_ref<A> a_ref_;
};

void usage1()
{
    A a;

    Safe safe;
    safe.use_ref( "hello" );          //null reference, do nothing
    safe.set_ref(a);
    safe.use_ref( "hello world!" );   //safe reference, Ok!
}

void usage2()
{
    safe_ref<int> si;
    si.use( [] (int& i ) {
        std::cout << i << std::endl;
    });

    int temp = 15;

    safe_ref<int> si2(temp);
    si2.use( [] (int& i ) {
        std::cout << i << std::endl;
    });

    si = ref(temp);
    si.use( [] (int& i ) {
        std::cout << i << std::endl;
    });
}
//----------------------------------------------------------------------------

It is similar to optional<T>, but in this case the idea is to not allow
access to internal data if the pointer is null, only allowing a safe usage

There is interest to add something like this to the std-lib?
Any comments or remarks?

Thanks and regards,
Fernando Pelliccioni.

--




--e89a8fb2058ebce85c04d0b41d13
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div>Hi all,<br></div><div><br></div><div>The motivation is to avoid code l=
ike the following...</div><div><br></div><div>//---------------------------=
-------------------------------------------------</div><div>#include &lt;io=
stream&gt;</div>
<div>#include &lt;string&gt;</div><div><br></div><div>struct A</div><div>{<=
/div><div>=A0 =A0 void do_something( std::string s ) const</div><div>=A0 =
=A0 {</div><div>=A0 =A0 =A0 =A0 std::cout &lt;&lt; &quot;do something with =
&quot; &lt;&lt; s &lt;&lt; &quot; and &quot; &lt;&lt; i_ &lt;&lt; &quot;\n&=
quot;;</div>
<div>=A0 =A0 }</div><div><br></div><div>=A0 =A0 int i_ =3D 99;</div><div>};=
</div><div><br></div><div>// unsafe traditional code</div><div>struct Unsaf=
e</div><div>{</div><div>=A0 =A0 void set_ref( A&amp; a )</div><div>=A0 =A0 =
{</div><div>=A0 =A0 =A0 =A0 a_ptr_ =3D std::addressof(a);</div>
<div>=A0 =A0 }</div><div><br></div><div>=A0 =A0 void use_ref( std::string s=
 ) const</div><div>=A0 =A0 {</div><div>=A0 =A0 =A0 =A0 if (a_ptr_ !=3D null=
ptr)</div><div>=A0 =A0 =A0 =A0 {</div><div>=A0 =A0 =A0 =A0 =A0 =A0 a_ptr_-&=
gt;do_something(s);</div><div>=A0 =A0 =A0 =A0 }</div>
<div>=A0 =A0 }</div><div><br></div><div>=A0 =A0 void use_ref_2( std::string=
 s ) const</div><div>=A0 =A0 {</div><div>=A0 =A0 =A0 =A0 //forgot to check =
for nullptr</div><div>=A0 =A0 =A0 =A0 a_ptr_-&gt;do_something(s);</div><div=
>=A0 =A0 } =A0 =A0</div><div><br>
</div><div>=A0 =A0 A* a_ptr_ =3D nullptr;<span class=3D"" style=3D"white-sp=
ace:pre"> </span>//I can&#39;t use A&amp; nor reference_wrapper&lt;A&gt;, n=
eed to be nullable.</div><div>};</div><div><br></div><div>void f()</div><di=
v>{</div>
<div>=A0 =A0 A a;</div><div><br></div><div>=A0 =A0 Unsafe unsafe;</div><div=
>=A0 =A0 unsafe.use_ref( &quot;hello&quot; ); =A0 =A0 =A0 =A0 =A0 =A0 =A0//=
null reference, do nothing, hope!</div><div>=A0 =A0 unsafe.set_ref(a);</div=
><div>=A0 =A0 unsafe.use_ref( &quot;hello world!&quot; ); =A0 =A0 =A0 //not=
-null reference, Ok!</div>
<div><br></div><div>=A0 =A0 Unsafe unsafe2;</div><div>=A0 =A0 unsafe2.use_r=
ef( &quot;hello&quot; ); =A0 =A0 =A0 =A0 =A0 =A0 =A0//null reference, do no=
thing, hope!</div><div>=A0 =A0 unsafe2.use_ref_2( &quot;hello&quot; ); =A0 =
=A0 =A0 =A0 =A0 =A0//null reference, Ops! =A0 =A0</div>
<div>}</div><div>//--------------------------------------------------------=
--------------------</div><div><br></div><div><br></div><div><br></div><div=
><br></div><div><br></div><div>The proposed solution:</div><div><br></div>
<div>//--------------------------------------------------------------------=
--------</div><div>// Proposed (draft)</div><div>//------------------------=
----------------------------------------------------</div><div><br></div>
<div>template &lt;typename T&gt;</div><div>class safe_ref</div><div>{</div>=
<div>public:</div><div>=A0 =A0 typedef T type;</div><div><br></div><div>=A0=
 =A0 explicit safe_ref()</div><div>=A0 =A0 =A0 =A0 : t_( nullptr )</div><di=
v>=A0 =A0 {}</div>
<div><br></div><div>=A0 =A0 explicit safe_ref(T&amp; t)</div><div>=A0 =A0 =
=A0 =A0 : t_( std::addressof(t) )</div><div>=A0 =A0 {}</div><div><br></div>=
<div>=A0 =A0 template &lt;typename Func&gt;</div><div>=A0 =A0 void use ( Fu=
nc f ) const</div><div>
=A0 =A0 {</div><div>=A0 =A0 =A0 =A0 if ( is_initialized() )</div><div>=A0 =
=A0 =A0 =A0 {</div><div>=A0 =A0 =A0 =A0 =A0 =A0 f( *t_ );</div><div>=A0 =A0=
 =A0 =A0 }</div><div>=A0 =A0 }</div><div><br></div><div>private:</div><div>=
=A0 =A0 bool is_initialized() const</div><div>
=A0 =A0 {</div><div>=A0 =A0 =A0 =A0 return t_ !=3D nullptr;</div><div>=A0 =
=A0 }</div><div><br></div><div><br></div><div>=A0 =A0 T* t_;</div><div>};</=
div><div><br></div><div>template &lt;typename T&gt;</div><div>inline safe_r=
ef&lt;T&gt; const ref(T&amp; t)</div>
<div>{</div><div>=A0 =A0 return safe_ref&lt;T&gt;(t);</div><div>}</div><div=
><br></div><div>template &lt;typename T&gt;</div><div>inline safe_ref&lt;T =
const&gt; const cref(T const&amp; t)</div><div>{</div><div>=A0 =A0 return s=
afe_ref&lt;T const&gt;(t);</div>
<div>}</div><div><br></div><div><br></div><div>//--------------------------=
--------------------------------------------------</div><div>// Usage</div>=
<div>//--------------------------------------------------------------------=
--------</div>
<div><br></div><div>#include &lt;iostream&gt;</div><div>#include &lt;string=
&gt;</div><div><br></div><div>struct A</div><div>{</div><div>=A0 =A0 void d=
o_something( std::string s ) const</div><div>=A0 =A0 {</div><div>=A0 =A0 =
=A0 =A0 std::cout &lt;&lt; &quot;A::do_something with &quot; &lt;&lt; s &lt=
;&lt; &quot; and &quot; &lt;&lt; i_ &lt;&lt; &quot;\n&quot;;</div>
<div>=A0 =A0 }</div><div><br></div><div>=A0 =A0 int i_ =3D 99;</div><div>};=
</div><div><br></div><div>struct Safe</div><div>{</div><div>=A0 =A0 void se=
t_ref( A&amp; a )</div><div>=A0 =A0 {</div><div>=A0 =A0 =A0 =A0 a_ref_ =3D =
ref(a);</div><div>=A0 =A0 }</div>
<div><br></div><div>=A0 =A0 void use_ref( std::string s ) const</div><div>=
=A0 =A0 {</div><div>=A0 =A0 =A0 =A0 a_ref_.use( [&amp;s] ( A&amp; a ) {</di=
v><div>=A0 =A0 =A0 =A0 =A0 =A0 a.do_something(s);</div><div>=A0 =A0 =A0 =A0=
 });</div><div>=A0 =A0 }</div><div><br>
</div><div>=A0 =A0 safe_ref&lt;A&gt; a_ref_;</div><div>};</div><div><br></d=
iv><div>void usage1()</div><div>{</div><div>=A0 =A0 A a;</div><div><br></di=
v><div>=A0 =A0 Safe safe;</div><div>=A0 =A0 safe.use_ref( &quot;hello&quot;=
 ); =A0 =A0 =A0 =A0 =A0//null reference, do nothing</div>
<div>=A0 =A0 safe.set_ref(a);</div><div>=A0 =A0 safe.use_ref( &quot;hello w=
orld!&quot; ); =A0 //safe reference, Ok! =A0 =A0</div><div>}</div><div><br>=
</div><div>void usage2()</div><div>{</div><div>=A0 =A0 safe_ref&lt;int&gt; =
si;</div><div>
=A0 =A0 si.use( [] (int&amp; i ) {</div><div>=A0 =A0 =A0 =A0 std::cout &lt;=
&lt; i &lt;&lt; std::endl;</div><div>=A0 =A0 });</div><div><br></div><div>=
=A0 =A0 int temp =3D 15;</div><div><br></div><div>=A0 =A0 safe_ref&lt;int&g=
t; si2(temp);</div><div>
=A0 =A0 si2.use( [] (int&amp; i ) {</div><div>=A0 =A0 =A0 =A0 std::cout &lt=
;&lt; i &lt;&lt; std::endl;</div><div>=A0 =A0 }); =A0 =A0</div><div><br></d=
iv><div>=A0 =A0 si =3D ref(temp);</div><div>=A0 =A0 si.use( [] (int&amp; i =
) {</div><div>=A0 =A0 =A0 =A0 std::cout &lt;&lt; i &lt;&lt; std::endl;</div=
>
<div>=A0 =A0 });</div><div>}</div><div>//----------------------------------=
------------------------------------------</div><div><br></div><div>It is s=
imilar to optional&lt;T&gt;, but in this case the idea is to not allow acce=
ss to internal data if the pointer is null, only allowing a safe usage</div=
>
<div><br></div><div>There is interest to add something like this to the std=
-lib?</div><div>Any comments or remarks?</div><div><br></div><div>Thanks an=
d regards,</div><div>Fernando Pelliccioni.</div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

--e89a8fb2058ebce85c04d0b41d13--

.


Author: DeadMG <wolfeinstein@gmail.com>
Date: Thu, 13 Dec 2012 11:36:49 -0800 (PST)
Raw View
------=_Part_45_26607857.1355427409229
Content-Type: text/plain; charset=ISO-8859-1

The reason the code is unsafe is because your Unsafe class does not, as it
should, take an A& in the constructor to initialize itself with. This is
simply the author not correctly constructing his class- as are all the
other public Initialize() or IsInitialized() or whatever methods. When your
constructor returns, your object is safe for use, and if you violate this
constraint, then the resulting unsafety is your own fault- and there's
nothing the Standard can do.

--




------=_Part_45_26607857.1355427409229
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

The reason the code is unsafe is because your Unsafe class does not, as it =
should, take an A&amp; in the constructor to initialize itself with. This i=
s simply the author not correctly constructing his class- as are all the ot=
her public Initialize() or IsInitialized() or whatever methods. When your c=
onstructor returns, your object is safe for use, and if you violate this co=
nstraint, then the resulting unsafety is your own fault- and there's nothin=
g the Standard can do.

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_45_26607857.1355427409229--

.


Author: Fernando Pelliccioni <fpelliccioni@gmail.com>
Date: Thu, 13 Dec 2012 21:30:07 -0300
Raw View
--14dae93997d32b220c04d0c5223f
Content-Type: text/plain; charset=ISO-8859-1

On Thu, Dec 13, 2012 at 4:36 PM, DeadMG <wolfeinstein@gmail.com> wrote:

> The reason the code is unsafe is because your Unsafe class does not, as it
> should, take an A& in the constructor to initialize itself with. This is
> simply the author not correctly constructing his class- as are all the
> other public Initialize() or IsInitialized() or whatever methods. When your
> constructor returns, your object is safe for use, and if you violate this
> constraint, then the resulting unsafety is your own fault- and there's
> nothing the Standard can do.


Not everything can be solved using references, there are times we need null
references.
How do you implement a linked list using references?
What is the purpose of pointers if references allow us to solve all our
problems?

We need null references, safe null references.

Another example of the need for null references:

struct B;

struct A
{
    B& b_ref_;
    int i_ = 1;
};

struct B
{
    A& a_ref_;
    int i_ = 2;
};

This code is Invalid.
We need to initialize the references during the object construction.
Impossible in this example.
To fix it, we should do this ...

struct B;

struct A
{
    B& b_ref_;

    A( B& b_ref ) : b_ref_(b_ref) {}
};

struct B
{
    A* a_ptr_;

    void set_a( A& a_ref )
    {
        a_ptr_  = std::addressof(a_ref);
    }
};

void f()
{
    B b;
    A a(b);
    b.set_a(a);
}

Now we depend on that A and B are correctly initialized.
We depend on ...

    b.set_a(a);

I'm thinking of a proposal involving certain changes in language.
But for now, I thought that this simple tool class library can help
(Obviously, I need to think of all possible uses)

Thanks and regards,
Fernando Pelliccioni

--




--14dae93997d32b220c04d0c5223f
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div class=3D"gmail_extra"><br><br><div class=3D"gmail_quote">On Thu, Dec 1=
3, 2012 at 4:36 PM, DeadMG <span dir=3D"ltr">&lt;<a href=3D"mailto:wolfeins=
tein@gmail.com" target=3D"_blank">wolfeinstein@gmail.com</a>&gt;</span> wro=
te:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;p=
adding-left:1ex">The reason the code is unsafe is because your Unsafe class=
 does not, as it should, take an A&amp; in the constructor to initialize it=
self with. This is simply the author not correctly constructing his class- =
as are all the other public Initialize() or IsInitialized() or whatever met=
hods. When your constructor returns, your object is safe for use, and if yo=
u violate this constraint, then the resulting unsafety is your own fault- a=
nd there&#39;s nothing the Standard can do.</blockquote>
</div><br></div><div class=3D"gmail_extra">Not everything can be solved usi=
ng references, there are times we need null references.<br></div><div class=
=3D"gmail_extra"><div class=3D"gmail_extra"><div class=3D"gmail_extra">How =
do you implement a linked list using references?</div>
<div class=3D"gmail_extra">What is the purpose of pointers if references al=
low us to solve all our problems?</div><div class=3D"gmail_extra"><br></div=
><div class=3D"gmail_extra">We need null references, safe null references.<=
/div>
<div class=3D"gmail_extra"><br></div><div class=3D"gmail_extra">Another exa=
mple of the need for null references:</div><div class=3D"gmail_extra"><br><=
/div><div class=3D"gmail_extra">struct B;</div><div class=3D"gmail_extra"><=
br></div>
<div class=3D"gmail_extra">struct A</div><div class=3D"gmail_extra">{</div>=
<div class=3D"gmail_extra">=A0 =A0 B&amp; b_ref_;</div><div class=3D"gmail_=
extra">=A0 =A0 int i_ =3D 1;</div><div class=3D"gmail_extra">};</div><div c=
lass=3D"gmail_extra">
<br></div><div class=3D"gmail_extra">struct B</div><div class=3D"gmail_extr=
a">{</div><div class=3D"gmail_extra">=A0 =A0 A&amp; a_ref_;</div><div class=
=3D"gmail_extra">=A0 =A0 int i_ =3D 2;</div><div class=3D"gmail_extra">};</=
div><div class=3D"gmail_extra">
<br></div><div class=3D"gmail_extra">This code is Invalid.=A0<br></div><div=
 class=3D"gmail_extra">We need to initialize the references during the obje=
ct construction. Impossible in this example.</div><div class=3D"gmail_extra=
">To fix it, we should do this ...</div>
<div class=3D"gmail_extra"><br></div><div class=3D"gmail_extra">struct B;</=
div><div class=3D"gmail_extra"><br></div><div class=3D"gmail_extra">struct =
A</div><div class=3D"gmail_extra">{</div><div class=3D"gmail_extra">=A0 =A0=
 B&amp; b_ref_;</div>
<div class=3D"gmail_extra"><br></div><div class=3D"gmail_extra">=A0 =A0 A( =
B&amp; b_ref ) : b_ref_(b_ref) {}</div><div class=3D"gmail_extra">};</div><=
div class=3D"gmail_extra"><br></div><div class=3D"gmail_extra">struct B</di=
v><div class=3D"gmail_extra">
{</div><div class=3D"gmail_extra">=A0 =A0 A* a_ptr_;</div><div class=3D"gma=
il_extra"><br></div><div class=3D"gmail_extra">=A0 =A0 void set_a( A&amp; a=
_ref )</div><div class=3D"gmail_extra">=A0 =A0 {</div><div class=3D"gmail_e=
xtra">=A0 =A0 =A0 =A0 a_ptr_ =A0=3D std::addressof(a_ref);</div>
<div class=3D"gmail_extra">=A0 =A0 }</div><div class=3D"gmail_extra">};</di=
v><div class=3D"gmail_extra"><br></div><div class=3D"gmail_extra">void f()<=
/div><div class=3D"gmail_extra">{</div><div class=3D"gmail_extra">=A0 =A0 B=
 b;</div><div class=3D"gmail_extra">
=A0 =A0 A a(b);</div><div class=3D"gmail_extra">=A0 =A0 b.set_a(a);</div><d=
iv class=3D"gmail_extra">}</div><div class=3D"gmail_extra"><br></div><div c=
lass=3D"gmail_extra">Now we depend on that A and B are correctly initialize=
d.</div><div class=3D"gmail_extra">
We depend on ...</div><div class=3D"gmail_extra"><br></div><div class=3D"gm=
ail_extra">=A0 =A0 b.set_a(a);</div><div class=3D"gmail_extra"><br></div><d=
iv class=3D"gmail_extra">I&#39;m thinking of a proposal involving certain c=
hanges in language.</div>
<div class=3D"gmail_extra">But for now, I thought that this simple tool cla=
ss library can help (Obviously, I need to think of all possible uses)</div>=
<div class=3D"gmail_extra"><br></div><div class=3D"gmail_extra">Thanks and =
regards,</div>
<div class=3D"gmail_extra">Fernando Pelliccioni</div></div></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

--14dae93997d32b220c04d0c5223f--

.


Author: Nevin Liber <nliber@gmail.com>
Date: Thu, 13 Dec 2012 18:47:02 -0600
Raw View
--000e0cd3b600b2b7f604d0c55ec5
Content-Type: text/plain; charset=ISO-8859-1

On Dec 13, 2012, at 6:30 PM, Fernando Pelliccioni <fpelliccioni@gmail.com>
wrote:

We need null references, safe null references.


How is our class semantically different than pointers (or const pointers,
if you don't want to allow reseating)?  I cannot syntactically use your
class in place of a reference, so other than adding a lot of complexity,
what problem does your class solve?

--




--000e0cd3b600b2b7f604d0c55ec5
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<html><head><meta http-equiv=3D"content-type" content=3D"text/html; charset=
=3Dutf-8"></head><body dir=3D"auto"><div>On Dec 13, 2012, at 6:30 PM, Ferna=
ndo Pelliccioni &lt;<a href=3D"mailto:fpelliccioni@gmail.com">fpelliccioni@=
gmail.com</a>&gt; wrote:</div>
<blockquote type=3D"cite"><div class=3D"gmail_extra"><div class=3D"gmail_qu=
ote">
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;p=
adding-left:1ex">We need null references, safe null references.</blockquote=
>
</div></div></blockquote><div><br></div><div>How is our class semantically =
different than pointers (or const pointers, if you don&#39;t want to allow =
reseating)? =A0I cannot syntactically use your class in place of a referenc=
e, so other than adding a lot of complexity, what problem does your class s=
olve?</div>
</body></html>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

--000e0cd3b600b2b7f604d0c55ec5--

.


Author: DeadMG <wolfeinstein@gmail.com>
Date: Fri, 14 Dec 2012 03:34:07 -0800 (PST)
Raw View
------=_Part_428_718636.1355484847847
Content-Type: text/plain; charset=ISO-8859-1


>
> How do you implement a linked list using references
>

Why would I need or want to do that? The current pointer implementations
are just fine.

 We need null references, safe null references.


You provide no evidence for this statement.

For your code sample, again, the problem is caused by sloppy coding, not
any unsafety in the language. Firstly, circular referencing like this is
generally a bad idea. But secondly,

struct B;

struct A
{
    A(B& b) : b_ptr_(&b) {}
    B* b_ptr_;
};

struct B
{
    B(A& a) : a_ptr_(&a) {}
    A* a_ptr_;
};

struct C {
    A a;
    B b;
    C() : a(b), b(a) {}
};

Now just instantiate C whenever you want a pair of b and a linked to each
other.


--




------=_Part_428_718636.1355484847847
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"auto"><div>How do =
you implement a linked list using references</div></div></blockquote><div><=
br></div><div>Why would I need or want to do that? The current pointer impl=
ementations are just fine.</div><div><br></div><blockquote class=3D"gmail_q=
uote" style=3D"margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-le=
ft-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"=
>&nbsp;We need null references, safe null references.</blockquote><div><br>=
</div><div>You provide no evidence for this statement.</div><div><br></div>=
<div>For your code sample, again, the problem is caused by sloppy coding, n=
ot any unsafety in the language. Firstly, circular referencing like this is=
 generally a bad idea. But secondly,</div><div><br></div><div><div>struct B=
;</div><div><br></div><div>struct A</div><div>{</div><div>&nbsp; &nbsp; A(B=
&amp; b) : b_ptr_(&amp;b) {}</div><div>&nbsp; &nbsp; B* b_ptr_;</div><div>}=
;</div><div><br></div><div>struct B</div><div>{</div><div>&nbsp; &nbsp; B(A=
&amp; a) : a_ptr_(&amp;a) {}</div><div>&nbsp; &nbsp; A* a_ptr_;</div><div>}=
;</div></div><div><br></div><div>struct C {</div><div>&nbsp; &nbsp; A a;</d=
iv><div>&nbsp; &nbsp; B b;</div><div>&nbsp; &nbsp; C() : a(b), b(a) {}</div=
><div>};</div><div><br></div><div>Now just instantiate C whenever you want =
a pair of b and a linked to each other.</div><div>&nbsp;</div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_428_718636.1355484847847--

.


Author: Zhihao Yuan <lichray@gmail.com>
Date: Sat, 15 Dec 2012 20:11:15 -0800 (PST)
Raw View
------=_Part_458_5639113.1355631076012
Content-Type: text/plain; charset=ISO-8859-1

On Friday, December 14, 2012 5:34:07 AM UTC-6, DeadMG wrote:
>
> How do you implement a linked list using references
>>
> Why would I need or want to do that? The current pointer implementations
> are just fine.
>
>>  We need null references, safe null references.
>
> You provide no evidence for this statement.
>

I agree with the concept of a safe nullable type, so please take a look at

http://kojot.sggw.waw.pl/~akrzemi1/optional/tr2.optional.proposal.html

An "optional" type wrapper.

--




------=_Part_458_5639113.1355631076012
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

On Friday, December 14, 2012 5:34:07 AM UTC-6, DeadMG wrote:<blockquote cla=
ss=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #=
ccc solid;padding-left: 1ex;"><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div =
dir=3D"auto"><div>How do you implement a linked list using references</div>=
</div></blockquote><div></div><div>Why would I need or want to do that? The=
 current pointer implementations are just fine.</div><div></div><blockquote=
 class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:=
1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left=
:1ex">&nbsp;We need null references, safe null references.</blockquote><div=
></div><div>You provide no evidence for this statement.</div></blockquote><=
div><br>I agree with the concept of a safe nullable type, so please take a =
look at<br><br>http://kojot.sggw.waw.pl/~akrzemi1/optional/tr2.optional.pro=
posal.html<br><br>An "optional" type wrapper.</div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_458_5639113.1355631076012--

.


Author: DeadMG <wolfeinstein@gmail.com>
Date: Sun, 16 Dec 2012 03:22:36 -0800 (PST)
Raw View
------=_Part_864_28601757.1355656956650
Content-Type: text/plain; charset=ISO-8859-1

Nullable type, and null reference, are not the same thing. I'm quite a way
in support of std::optional.

--




------=_Part_864_28601757.1355656956650
Content-Type: text/html; charset=ISO-8859-1

Nullable type, and null reference, are not the same thing. I'm quite a way in support of std::optional.

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_864_28601757.1355656956650--

.


Author: Zhihao Yuan <lichray@gmail.com>
Date: Sun, 16 Dec 2012 11:30:33 -0600
Raw View
On Sun, Dec 16, 2012 at 5:22 AM, DeadMG <wolfeinstein@gmail.com> wrote:
> Nullable type, and null reference, are not the same thing.

I don't think so.  An optional<T&> is obviously what a safe_ref<T> can achieve.

--
Zhihao Yuan, ID lichray
The best way to predict the future is to invent it.
___________________________________________________
4BSD -- http://4bsd.biz/

--




.


Author: DeadMG <wolfeinstein@gmail.com>
Date: Sun, 16 Dec 2012 16:34:47 -0800 (PST)
Raw View
------=_Part_403_16005104.1355704487697
Content-Type: text/plain; charset=ISO-8859-1

So your argument in favour of this is that it's trivially achievable using
a much more generic solution that should be Standardised anyway?

--




------=_Part_403_16005104.1355704487697
Content-Type: text/html; charset=ISO-8859-1

So your argument in favour of this is that it's trivially achievable using a much more generic solution that should be Standardised anyway?

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_403_16005104.1355704487697--

.


Author: Zhihao Yuan <lichray@gmail.com>
Date: Sun, 16 Dec 2012 18:44:11 -0600
Raw View
On Sun, Dec 16, 2012 at 6:34 PM, DeadMG <wolfeinstein@gmail.com> wrote:
> So your argument in favour of this is that it's trivially achievable using a
> much more generic solution that should be Standardised anyway?

Yes.  While optional<> is more generic, I see no overhead to use it instead of
a safe_ref<>.  And, as many people pointed out, generic nullable type is a
must-have in a modern type system, like what we have seen in ML and Haskell.

--
Zhihao Yuan, ID lichray
The best way to predict the future is to invent it.
___________________________________________________
4BSD -- http://4bsd.biz/

--




.