2010-09-09 73 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