C ++ 0x和Friend函数以及boost :: make_shared

时间:2010-09-09 00:02:08

标签: c++11

如果我有一个私有构造的类,使用boost :: make_shared在该类的成员函数内构造该类的shared_ptr将使用gcc 4.6发出编译器错误。


#include "boost/shared_ptr.hpp"
#include "boost/make_shared.hpp"


class Foo  
{  
private:  
    Foo(int a){};  
public:  
    static boost::shared_ptr do_foo(){ return boost::make_shared(5); }
    friend template boost::shared_ptr boost::make_shared( Arg1 && arg1, Args && ... args );
}  


int main()
{
    auto f = Foo::do_foo();
}

调用Foo::do_foo将导致编译器错误。

有什么想法吗?

编辑包含可编辑的代码。

2 个答案:

答案 0 :(得分:3)

不幸的是,没有指定哪个函数实际调用make_shared中的构造函数,因此您无法将该函数作为朋友。如果你有一个像这样的私有构造函数的类,那么你就不能用make_shared构造一个实例。

但是,您可以做的是使用公共构造函数创建一个派生类,该构造函数调用相应的基类构造函数,并使该派生类成为朋友(因此它可以调用私有构造函数):

class Foo
{
private:  
    Foo(int a){};  
public:  
    static boost::shared_ptr do_foo();
    friend class DerivedFoo;
};

class DerivedFoo: public Foo
{
public:
    DerivedFoo(int a):
        Foo(a)
    {}
};

boost::shared_ptr<Foo> Foo::do_foo(){ return boost::make_shared<DerivedFoo>(5); }

如果DerivedFoo位于定义do_foo的.cpp文件中的匿名命名空间中,则其他.cpp文件中的函数仍然无法直接构造Foo的任何实例,并且用户将无法告诉他们实际拥有的是DerivedFoo

答案 1 :(得分:0)

您至少需要在几个地方提供模板参数。

class Foo  
{  
private:  
    Foo(int a){};  
public:  
    static boost::shared_ptr<Foo> do_foo(){ return boost::make_shared<Foo>(5); }
    friend template boost::shared_ptr<Foo> boost::make_shared<Foo>( Arg1 && arg1, Args && ... args );
}