
On Sun, 2008-07-27 at 18:25 +0300, Peter Dimov wrote:
You should be able to make it work by making the appropriate make_shared overload a friend:
template< class T, class A1, class A2 > friend boost::shared_ptr< T > boost::make_shared( A1 const & a1, A2 const & a2 );
Good idea, thanks. It would also render create() useless, since the user could call make_shared directly. Sadly, it doesn't work for me. I've tried it with GCC 4.3: #include <memory> class A { private: A() {} public: static std::shared_ptr< A > create() { return std::make_shared< A >(); } template< typename... Args > friend std::shared_ptr< A > std::make_shared( Args... ); }; int main() { A::create(); } which fails, because the implementation forwards the ctor call into some nested functions. Here's the (terrible to read) output: frey@fiasko:~/work/test/make_shared_2$ g++ -std=c++0x -pedantic -O3 t.cc -o t && ./t t.cc: In constructor ‘std::_Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp>::_Sp_counted_ptr_inplace(_Alloc) [with _Tp = A, _Alloc = std::allocator<A>, __gnu_cxx::_Lock_policy _Lp = _S_mutex]’: /home/frey/work/gcc-4.3.1-install/lib/gcc/i686-pc-linux-gnu/4.3.1/../../../../include/c++/4.3.1/bits/boost_sp_shared_count.h:293: instantiated from ‘std::__shared_count<_Lp>::__shared_count(std::_Sp_make_shared_tag, _Tp*, _Alloc, _Args&& ...) [with _Tp = A, _Alloc = std::allocator<A>, _Args = , __gnu_cxx::_Lock_policy _Lp = _S_mutex]’ /home/frey/work/gcc-4.3.1-install/lib/gcc/i686-pc-linux-gnu/4.3.1/../../../../include/c++/4.3.1/tr1_impl/boost_shared_ptr.h:509: instantiated from ‘std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::_Sp_make_shared_tag, _Alloc, _Args&& ...) [with _Alloc = std::allocator<A>, _Args = , _Tp = A, __gnu_cxx::_Lock_policy _Lp = _S_mutex]’ /home/frey/work/gcc-4.3.1-install/lib/gcc/i686-pc-linux-gnu/4.3.1/../../../../include/c++/4.3.1/tr1_impl/boost_shared_ptr.h:926: instantiated from ‘std::shared_ptr<_Tp>::shared_ptr(std::_Sp_make_shared_tag, _Alloc, _Args&& ...) [with _Alloc = std::allocator<A>, _Args = , _Tp = A]’ /home/frey/work/gcc-4.3.1-install/lib/gcc/i686-pc-linux-gnu/4.3.1/../../../../include/c++/4.3.1/tr1_impl/boost_shared_ptr.h:1104: instantiated from ‘std::shared_ptr<_Tp> std::allocate_shared(_Alloc, _Args&& ...) [with _Tp = A, _Alloc = std::allocator<A>, _Args = ]’ /home/frey/work/gcc-4.3.1-install/lib/gcc/i686-pc-linux-gnu/4.3.1/../../../../include/c++/4.3.1/tr1_impl/boost_shared_ptr.h:1119: instantiated from ‘std::shared_ptr<_Tp> std::make_shared(_Args&& ...) [with _Tp = A, _Args = ]’ t.cc:9: instantiated from here t.cc:6: error: ‘A::A()’ is private /home/frey/work/gcc-4.3.1-install/lib/gcc/i686-pc-linux-gnu/4.3.1/../../../../include/c++/4.3.1/bits/boost_sp_shared_count.h:177: error: within this context frey@fiasko:~/work/test/make_shared_2$ Is this a bug in GCC's implementation of make_shared and I should file a bug report for it? Is it intended to standardize that the above code should work? Regards, Daniel BTW: I just filed another bug for GCC's make_shared, <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36949>, but there is IMHO nothing unclear about that... :)