我有一個(免費)函數模板,看起來像這樣專業生產與模板
template <typename T>
T get();
我現在要專注這個功能的一類,這本身就是一個模板,模板。但是我的編譯器不想編譯它,現在我問的是否可能,以及我如何實現它。只是爲理念,代碼可能看起來如下:(不編譯)
template <>
template <typename T>
foo_type<T> get<foo_type<T>>()
我有一個(免費)函數模板,看起來像這樣專業生產與模板
template <typename T>
T get();
我現在要專注這個功能的一類,這本身就是一個模板,模板。但是我的編譯器不想編譯它,現在我問的是否可能,以及我如何實現它。只是爲理念,代碼可能看起來如下:(不編譯)
template <>
template <typename T>
foo_type<T> get<foo_type<T>>()
你在做什麼叫做部分專業化功能模板。但是部分功能模板的專門化是不允許的。函數模板的重載是允許的,但在這種情況下也是不可能的,因爲函數只有返回類型,並且不允許重載類型的重載。
因此,解決辦法是這樣的:
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)
用於幫助編譯器選擇正確的過載。如果T
比foo<U>
其它,則第一過載將被選擇爲傳遞給它的參數的類型將是T*
而不是foo<U>*
。如果T
是foo<U>
,那麼第二個重載將由編譯器選擇,因爲它是更多專用的,並且可以接受在此情況下傳遞給它的參數,即foo<U>*
。
正如納瓦茲表示,該標準只是不允許你這樣做。但是,您可以將實現提取到類的靜態方法中,並部分專門化該類。
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(); }
現在,看到解決方案,這是顯而易見的痛苦。謝謝!但現在我得到一個鏈接器錯誤..任何想法? – cooky451 2012-03-03 01:45:06
錯誤,基於返回類型的重載不起作用... – Xeo 2012-03-03 01:45:15
@Xeo:糟糕。是。你是對的。當我發佈它時,我覺得我做錯了什麼,但是搞不清楚。 – Nawaz 2012-03-03 01:46:50