Boost C++ Libraries: Ticket #2481: make_shared and allocate_shared friendship https://svn.boost.org/trac10/ticket/2481 <p> It is currently vary difficult to have a class with private constructors use make_shared and allocate_shared. This same classes are some ideal candidates for private constructors because any class that derives from enable_shared_from_this should probably have private constructors to prevent misuse. Simplifying friend declarations for these functions would be very helpful. </p> <p> For example: </p> <div class="wiki-code"><div class="code"><pre><span class="k">class</span> <span class="nc">Foo</span> <span class="o">:</span> <span class="k">public</span> <span class="n">enable_shared_from_this</span><span class="o">&lt;</span><span class="n">Foo</span><span class="o">&gt;</span> <span class="p">{</span> <span class="k">friend</span> <span class="k">class</span> <span class="nc">make_shared_access</span><span class="p">;</span> <span class="n">Foo</span><span class="p">();</span> <span class="p">};</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span> <span class="n">shared_ptr</span><span class="o">&lt;</span><span class="n">Foo</span><span class="o">&gt;</span> <span class="n">foo</span><span class="p">(</span> <span class="n">make_shared</span><span class="o">&lt;</span><span class="n">Foo</span><span class="o">&gt;</span><span class="p">()</span> <span class="p">);</span> <span class="p">}</span> </pre></div></div> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/2481 Trac 1.4.3 Michael Marcin <mike.marcin@…> Thu, 06 Nov 2008 18:39:16 GMT attachment set https://svn.boost.org/trac10/ticket/2481 https://svn.boost.org/trac10/ticket/2481 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">make_shared_access.patch</span> </li> </ul> Ticket Michael Marcin <mike.marcin@…> Thu, 06 Nov 2008 18:41:25 GMT <link>https://svn.boost.org/trac10/ticket/2481#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/2481#comment:1</guid> <description> <p> Added a brute force patch that implements this for c++03 against boost 1.36 release. I left variadic template support as a todo because I don't know the syntax and don't have a compiler for it. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Frank Mori Hess</dc:creator> <pubDate>Fri, 12 Dec 2008 17:26:41 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/2481#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/2481#comment:2</guid> <description> <p> One limitation of your solution: suppose I have private constructors and a static factory function for a class, and the factory function returns a shared_ptr. If I make make_shared_access a friend, it opens a hole where people can still create objects of the class without using the factory function by using make_shared or allocate_shared directly. </p> </description> <category>Ticket</category> </item> <item> <author>Jonathan Wakely <jwakely.boost@…></author> <pubDate>Wed, 04 Feb 2009 13:16:20 GMT</pubDate> <title>cc set https://svn.boost.org/trac10/ticket/2481#comment:3 https://svn.boost.org/trac10/ticket/2481#comment:3 <ul> <li><strong>cc</strong> <span class="trac-author">jwakely.boost@…</span> added </li> </ul> <p> Right, you don't even need the make_shared_access extension to open that hole, the design is compromised if you declare make_shared or allocate_shared as a friend. </p> <p> Given: </p> <pre class="wiki">class MustUseFactory { MustUseFactory() { } public: static shared_ptr&lt;MustUseFactory&gt; create(); }; </pre><p> You can still use make_shared by using aliasing: </p> <pre class="wiki">shared_ptr&lt;MustUseFactory&gt; MustUseFactory::create() { typedef aligned_storage&lt;sizeof(MustUseFactory)&gt; Storage; shared_ptr&lt;Storage&gt; storage = make_shared&lt;Storage&gt;(); MustUseFactory* p = new (storage-&gt;address()) MustUseFactory(); return shared_ptr&lt;MustUseFactory&gt;(storage, p); } </pre><p> This doesn't work with enable_shared_from_this, I leave that as an exercise for the reader ;-) </p> Ticket Peter Dimov Sat, 28 Feb 2009 17:07:38 GMT status, milestone changed https://svn.boost.org/trac10/ticket/2481#comment:4 https://svn.boost.org/trac10/ticket/2481#comment:4 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">assigned</span> </li> <li><strong>milestone</strong> <span class="trac-field-old">Boost 1.38.0</span> → <span class="trac-field-new">Boost 1.39.0</span> </li> </ul> Ticket Peter Dimov Sat, 07 Mar 2009 21:22:19 GMT <link>https://svn.boost.org/trac10/ticket/2481#comment:5 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/2481#comment:5</guid> <description> <p> It still seems to me that the best course of action is to make allocate_shared use A::construct. Unfortunately, this doesn't work with C++03 allocators, whose construct method only takes a single T const&amp; argument. C++0x allocators are OK, but changing boost::allocate_shared to call construct will make it fail for C++03 allocators. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Peter Dimov</dc:creator> <pubDate>Tue, 01 Dec 2009 01:47:06 GMT</pubDate> <title>milestone changed https://svn.boost.org/trac10/ticket/2481#comment:6 https://svn.boost.org/trac10/ticket/2481#comment:6 <ul> <li><strong>milestone</strong> <span class="trac-field-old">Boost 1.39.0</span> → <span class="trac-field-new">To Be Determined</span> </li> </ul> Ticket Peter Dimov Thu, 24 Feb 2011 22:08:43 GMT status changed https://svn.boost.org/trac10/ticket/2481#comment:7 https://svn.boost.org/trac10/ticket/2481#comment:7 <ul> <li><strong>status</strong> <span class="trac-field-old">assigned</span> → <span class="trac-field-new">new</span> </li> </ul> Ticket jwakely.boost@… Tue, 08 Nov 2011 17:28:52 GMT <link>https://svn.boost.org/trac10/ticket/2481#comment:8 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/2481#comment:8</guid> <description> <p> Using std::allocator_traits&lt;A&gt;::construct will work with C++11 or C++03 allocators, which is what LWG 2070 suggests and what I've implemented for GCC 4.7 </p> <p> Of course that requires a C++11 library that provides allocator_traits </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Peter Dimov</dc:creator> <pubDate>Wed, 12 Feb 2014 00:45:48 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/2481#comment:9 https://svn.boost.org/trac10/ticket/2481#comment:9 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> <p> boost::allocate_shared now uses std::allocator_traits&lt;&gt;::construct and destroy (if available), as per LWG 2070. </p> Ticket