I have written a class with protected constructor, so that new instances can only be produced with a static create() function which returns shared_ptr's to my class. To provide efficient allocation I'd like to use boost::make_shared inside the create function, however the compiler complains that my class constructor is protected inside boost::make_shared. I decided to my boost::make_shared a friend of my class but I'm puzzled about the syntax. I tried
template< class T, class A1, class A2 >
friend boost::shared_ptr<Connection> boost::make_shared(const ConnectionManagerPtr&, const std::string&);
but the compiler gived me syntax errors. Please help.
You don't need to template the
friend
part, but you need to signify that thefriend
function is a template:That works with Comeau and current GCC versions but fails with VC. Better would be the following form:
That works across multiple compilers now - i tested it on VC8, VC10, GCC 4.2, GCC 4.5 and Comeau 4.3.
Alternatively using a qualified name to refer to a particular instance of the function template as Martin does should work and does with Comeau, but GCC chokes on it.
A useful alternative that doesn't depend on the implementation details of
make_shared()
(and thus also works with VC10s TR1 implementation) is to use the pass-key-idiom for access-protection of the constructor and to befriend thecreate()
function instead, e.g.:I think that is not the right place to use make_shared. Just construct your object with operator new and pass the pointer to shared_ptr constructor. That way you don't need to be friends with anyone.
BTW, why template arguments and function arguments are of different type?
Just a summary of how a complete version may look like:
I would try without the
template
part. After all, you want a specific instantiation of the (template) function to be a friend of your class, aren't you? Doeswork?
If that's not the solution, it might be helpful to give us the compiler messages you're getting ...
I ended up using the below simple solution to enforce shared ownership. No friendship required.
Below are some macros I wrote up to do this for you. In your case, you would use:
Macro definitions: