2012-03-03 44 views
3

我有一個(免費)函數模板,看起來像這樣專業生產與模板

template <typename T> 
T get(); 

我現在要專注這個功能的一類,這本身就是一個模板,模板。但是我的編譯器不想編譯它,現在我問的是否可能,以及我如何實現它。只是爲理念,代碼可能看起來如下:(不編譯)

template <> 
template <typename T> 
foo_type<T> get<foo_type<T>>() 

回答

3

你在做什麼叫做部分專業化功能模板。但是部分功能模板的專門化是不允許的。函數模板的重載是允許的,但在這種情況下也是不可能的,因爲函數只有返回類型,並且不允許重載類型的重載。

因此,解決辦法是這樣的:

namespace details 
{ 
    template <typename T> 
    struct worker 
    { 
     static T get(); 
    }; 

    template <typename T> //partial specialization of class is allowed 
    struct worker<foo<T>> 
    { 
     static foo<T> get(); 
    }; 

} 

template <typename T> 
T get() 
{ 
    return details::worker<T>::get(); 
} 

你也可以使用重載如果定義他們採取一個參數,從而使超載有效:

namespace details 
{ 
    template <typename T> 
    static T get(T*); 

    template <typename T> 
    static foo<T> get(foo<T>*); //now the overload is valid 

} 

template <typename T> 
T get() 
{ 
    return details::get<T>(static_cast<T*>(0)); 
} 

注意,參數static_cast<T*>(0)用於幫助編譯器選擇正確的過載。如果Tfoo<U>其它,則第一過載將被選擇爲傳遞給它的參數的類型將是T*而不是foo<U>*。如果Tfoo<U>,那麼第二個重載將由編譯器選擇,因爲它是更多專用的,並且可以接受在此情況下傳遞給它的參數,即foo<U>*

+0

現在,看到解決方案,這是顯而易見的痛苦。謝謝!但現在我得到一個鏈接器錯誤..任何想法? – cooky451 2012-03-03 01:45:06

+0

錯誤,基於返回類型的重載不起作用... – Xeo 2012-03-03 01:45:15

+0

@Xeo:糟糕。是。你是對的。當我發佈它時,我覺得我做錯了什麼,但是搞不清楚。 – Nawaz 2012-03-03 01:46:50

2

正如納瓦茲表示,該標準只是不允許你這樣做。但是,您可以將實現提取到類的靜態方法中,並部分專門化該類。

template<class T> 
struct get_impl{ 
    static T get(){ ... } 
}; 

template<class T> 
struct get_impl<foo_type<T> >{ 
    static foo_type<T> get(){ ... } 
}; 

template<class T> 
T get(){ return get_impl<T>::get(); }