2010-09-09 75 views
1

如果我有一个私有构造类,使用boost :: make_shared从该类的成员函数内构造该类的shared_ptr会发出编译器错误使用gcc 4.6。C++ 0x和Friend函数和boost :: make_shared


#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的调用将导致编译器错误。

有什么想法?

被编辑为包含可编译代码。

回答

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

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); 
} 
+0

什么是Arg1和Args? – sellibitze 2010-09-10 08:29:40

+0

@sellibitze可能不应该在那里,但我只是复制粘贴OP的代码。 'make_shared'确实需要可变数量的参数,并将它们传递给目标类型的构造函数。 – kwatford 2010-09-10 14:09:23

+0

我可以发誓,我做到了...... – Raindog 2010-09-10 19:24:06