2009-09-19 183 views
2

對於一個普通的C++函數,它可能在參數列表不顯示模板參數:類的構造函數與非參數模板類型

template<typename T> 
T default_construct() 
{ 
    return T(); 
} 

some_type x = default_construct<some_type>(); 

即使調用此我使用的類型不在參數列表中,我仍然可以將它傳遞給函數。現在,我想這樣做在類的構造函數:

struct Base; 

template<typename T> 
Base* allocate() 
{ 
    return new T; //Assume T derives from Base... 
} 

struct factory { 
    template<typename T> 
    factory() 
     : func(allocate<T>) 
    {} 

    std::tr1::function<Base*()> func; 
}; 

,但我不能找到一種方法,參數向構造函數時,我想構建的factory一個實例。

有沒有辦法做到這一點沒有把類變成模板類或發送一些未使用的對象到構造函數?

回答

9

不,沒有辦法做到這一點。在14.8.1/5在標準的說明解釋了爲什麼

[注:由於顯式模板參數列表如下函數模板名稱,因爲轉換成員函數模板和構造成員函數模板被稱爲不使用功能名稱,還有沒有辦法爲這些函數模板提供顯式的模板參數列表。 ]

當然,它不需要是您發送的T對象。它可以是已經T編碼,其類型

template<typename T> struct type2type { }; 

struct factory { 
    template<typename T> 
    factory(type2type<T>) 
     : func(allocate<T>) 
    {} 

    std::tr1::function<Base*()> func; 
}; 

factory f((type2type<Foo>())); 
+0

好吧,標準答案很引人注目。謝謝。 – CAdaker 2009-09-19 02:48:43

3

沒有任何對象,你不能。使用「類型標籤對象」來調用給定類型的未使用對象。您可以創建每種類型的全局變量,也可以每次使用默認的構造函數。

你可以合理地希望,如果構造函數是內聯的,那麼類型標籤永遠不會被創建。

0

litb's和wrang-wrang的答案很好。作爲一種可能性,您可以考慮將所有(非複製)構造函數聲明爲私有或受保護的,並創建一個或多個靜態成員函數模板factory create<T>()。然後,定義一個工廠實例,而不是

factory<SomeType> f;      // 1 (doesn't compile) 

你會寫

factory f(factory::create<SomeType>()); // 2 

顯然不是一樣漂亮(1),但恕我直言不是使用類型標籤稍微清晰。 (編譯器將在實踐中消除副本。)

順便說一句,有沒有原因,你不能簡單地使factory類模板?然後從(1)的語法將被編譯。 (但這意味着不同類型的工廠不能被分配到另一個工廠)。