Smart pointer that cannot be nullptr Sometimes I need a reference counting smart pointer that should not be nullptr. For example, I want to share a very heavy object without copying. And it's more convenient to place it on the heap. So I could use a shared_ptr. Also, I don't need to assign nullptr to this pointer or reassign it. So I don't want to check for nullptr in code that uses it. I think it would be useful to have a pointer that cannot be nullptr and cannot be reassigned.

I wrote a small prototype that has this features.

 #include &lt;iostream&gt;
 #include &lt;string&gt;
 #include &lt;memory&gt;
 #include &lt;exception&gt;
 #include &lt;thread&gt;

 using namespace std;

 // Box cannot hold nullptr
 template&lt;class T&gt;
 class Box
 {
 public:  
     template &lt;class... Args&gt;
     static Box&lt;T&gt; create(Args&amp;&amp;... args)
     {
         return Box&lt;T&gt;(make_shared&lt;T&gt;(std::forward&lt;Args&gt;(args)...));
     }

     T * operator-&gt; () const
     {
         return ptr.operator -&gt; ();
     }
 private:
     Box(const shared_ptr&lt;T&gt; &amp; ptr)
         : ptr(ptr)
     {}

     shared_ptr&lt;T&gt; ptr;
 };

 struct Test
 {
     Test(int i, double d, const string &amp; s)
         : i(i), d(d), s(s)
     {
         cout &lt;&lt; "Test ctor" &lt;&lt; endl;
     }

     ~Test()
     {
         cout &lt;&lt; "Test dtor" &lt;&lt; endl;
     }

     Test(const Test &amp; test) = delete;
     Test(Test &amp;&amp; test) = delete;
     Test &amp; operator = (const Test &amp; test) = delete;
     Test &amp; operator = (Test &amp;&amp; test) = delete;

     int i;
     double d;
     string s;
 };

 void print(const Box&lt;Test&gt; &amp; test)
 {
     // there is no need to check for nullptr
     cout &lt;&lt; test-&gt;i &lt;&lt; " " &lt;&lt; test-&gt;d &lt;&lt; " " &lt;&lt; test-&gt;s &lt;&lt; endl;
 }

 void twice(Box&lt;Test&gt; test)
 {
     // there is no need to check for nullptr
     test-&gt;i *= 2;
     test-&gt;d *= 2;
     test-&gt;s += test-&gt;s;
 }

 /*
 stdout:
 Test ctor
 42 3.14 hello
 84 6.28 hellohello
 Test dtor
 */
 int main()
 {
     Box&lt;Test&gt; test = Box&lt;Test&gt;::create(42, 3.14, "hello");
     print(test);

     thread t(twice, test);
     t.join();

     print(test);
 }


Is this code correct? And is this a good approach?

Update:
It looks like I found a ready solution https://github.com/dropbox/nn

Related discussions:

1) https://groups.google.com/a/isocpp.org/forum/#!topic/std-proposals/5TPClBA1fs8

2) http://boost.2283326.n4.nabble.com/Why-no-non-null-smart-pointers-td2642959.html

3) https://lists.boost.org/Archives/boost/2013/10/206732.php
Well, in principle having non-nullable pointers, smart or not, is a good thing. It's just a shame that nullability is not an optional non-default trait (not only for pointers, but for all types; for numbers non-zeroability might be an interesting companion-trait, which incidentally makes the former more efficient).

Your implementation of it leaves something to be desired though, because you completely block conversion from "normal" nullable pointers to your non-nullable one and back. That severely limits your types utility.
Also, one expects a lot more functionality from a pointer-like type, like more conversions, more operators, and the rest of the smart-pointer-interface, at least as far as compatible with the design-goals.

Now let's look at the code of your prototype:


Separate your new smart-pointer from the test-code, and make it a self-contained header-only-library.
Never use using namespace std; in an include-file, not that it is much better in a source-file. Read "Why is “using namespace std;” considered bad practice?" for the reasons.
As said above, you need loads more accessors, and all the other functons, member and free, which comprise the interface for a smart-pointer.
If you use private inheritance, you have an easier time passing through the needed interface with using than writing it from scratch.


And the code of your test:


Only explicitly flush a stream if you really need to. Doing so frivolously is quote costly.
If you want to output a single character to a stream, consider doing so explicitly instead of with a length-1 C-string. It's potentially slightly more efficient.