How to make boost::make_shared a friend of my class

后端 未结 6 1321
借酒劲吻你
借酒劲吻你 2021-02-03 12:28

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

6条回答
  •  孤街浪徒
    2021-02-03 13:15

    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());
    }
    

提交回复
热议问题