How do I call ::std::make_shared on a class with only protected or private constructors?

Looking at the requirements for std::make_shared in 20.7.2.2.6 shared_ptr creation util.smartptr.shared. Create, paragraph 1: Requires: The expression ::new (pv) T(std::forward(args)...), where pv has type void* and points to storage suitable to hold an object of type T, shall be well formed. A shall be an allocator (17.6.3.5).

The copy constructor and destructor of A shall not throw exceptions Since the requirement is unconditionally specified in terms of that expression and things like scope aren't taken into account, I think tricks like friendship are right out A simple solution is to derive from A This needn't require making A an interface or even a polymorphic type interface in header std::shared_ptr make_a(); // implementation in source namespace { struct concrete_A: public A {}; } // namespace std::shared_ptr make_a() { return std::make_shared(); }.

Looking at the requirements for std::make_shared in 20.7.2.2.6 shared_ptr creation util.smartptr.shared. Create, paragraph 1: Requires: The expression ::new (pv) T(std::forward(args)...), where pv has type void* and points to storage suitable to hold an object of type T, shall be well formed. A shall be an allocator (17.6.3.5).

The copy constructor and destructor of A shall not throw exceptions. Since the requirement is unconditionally specified in terms of that expression and things like scope aren't taken into account, I think tricks like friendship are right out. A simple solution is to derive from A.

This needn't require making A an interface or even a polymorphic type. // interface in header std::shared_ptr make_a(); // implementation in source namespace { struct concrete_A: public A {}; } // namespace std::shared_ptr make_a() { return std::make_shared(); }.

Oh, that's a very clever answer, and possibly better than another one I had thought of. – Omnifarious yesterday +1 for beating me to it – Alf P. Steinbach yesterday One question though, won't the shared_ptr delete an A and not a concrete_A, and couldn't this cause problems?

– Omnifarious yesterday 2 Ahh, it's because shared_ptr stores a deleter at the time of instantiation, and if you're using make_shared the deleter absolutely has to be using the right type. – Omnifarious yesterday I'm accepting your answer because it is a good answer. And while I think I like mine better, I think it's cheesy to accept your own answer when there is a perfectly acceptable answer that someone else made.

– Omnifarious 15 hours ago.

This answer is probably better, and the one I'll likely accept. But I also came up with a method that's uglier, but does still let everything still be inline and doesn't require a derived class: #include class A { struct this_is_private { }; public: explicit A(const this_is_private &) {} static ::std::shared_ptr create() { return ::std::make_shared(this_is_private{}); } protected: A(const A &) = delete; const A &operator =(const A &) = delete; }; ::std::shared_ptr foo() { return A::create(); }.

2 Actually, I am a huge fan of those meaningless structures used only as keys. I prefer this to Luc's solution, but that might be my biais against inheritance. – Matthieu M.

Yesterday 1 Agreed, I like this better as well. – ildjarn 16 hours ago One advantage this has is that it works even if the constructor is supposed to be private. The other only works if the constructor is protected so that a derived class has access to it.

– Omnifarious 15 hours ago.

Static std::shared_ptr create() { std::shared_ptr pA(new A()); return pA; }.

1 That works great. But ::std::make_shared has functionality above and beyond simply making a shared_ptr to something. It allocates the reference count along with the object so they're located close to each other.

I really, really want to use ::std::make_shared. – Omnifarious yesterday The deleted assigment and copy operators forbid this – Dani yesterday.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions