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
You don't need to template the friend
part, but you need to signify that the friend
function is a template:
friend boost::shared_ptr boost::make_shared<>(/* ... */);
// ^^
That works with Comeau and current GCC versions but fails with VC. Better would be the following form:
friend boost::shared_ptr boost::make_shared(/* ... */);
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 the create()
function instead, e.g.:
class Connection {
// ...
public:
class Key {
friend boost::shared_ptr create(const ConnectionManagerPtr&,
const std::string&);
Key() {}
};
Connection(const ConnectionManagerPtr&, const std::string&, const Key&);
};
boost::shared_ptr create(const ConnectionManagerPtr& p,
const std::string& s)
{
return boost::make_shared(p, s, Connection::Key());
}