Looking at the requirements for std::make_shared in 20.7.2.2.6 shared_ptr creation [util.smartptr.shared.create], paragraph 1:
Requires:Requires: The expression ::new (pv) T(std::forward(args)...)
::new (pv) T(std::forward<Args>(args)...), where pvpvhas type void*void*and points to storage suitable to hold an object of type TT, shall be well formed. AAshall be an allocator (17.6.3.5). The copy constructor and destructor of AAshall 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<A> make_a(); // implementation in source namespace { struct concrete_A: public A {}; } // namespace std::shared_ptr<A> make_a() { return std::make_shared<concrete_A>(); }