[英]Specialization of function for a specific template type
考慮以下:
template <typename TResult> inline TResult _from_string(const string& str);
template <> inline unsigned long long _from_string<unsigned long long>(const string& str) {
return stoull(str);
}
我可以這樣調用該函數:
auto x = _from_string<unsigned long long>("12345");
現在,我想為vector
編寫另一種專門化,即:
template <typename T> inline vector<T> _from_string<vector<T>>(const string& str) {
// stuff that should be done only if the template parameter if a vector of something
}
這樣我就可以做這樣的事情:
auto x = _from_string<vector<int>>("{1,2,3,4,5}");
但是,當我編譯該函數(在MSVC 2015下)時,出現錯誤C2768:“非法使用顯式模板參數”,這是有道理的,因為我不應該在專業化中使用新的模板參數。
如何重寫vector
專門化使其起作用?
功能模板只能是完全專業的 ,不能是部分專業的 ; 但是類模板可以。
// primary class template
template <typename T>
struct X {
static T _from_string(const string& str);
};
// full specialization for unsigned long long
template <>
struct X<unsigned long long> {
static unsigned long long _from_string(const string& str) {
return stoull(str);
}
};
// partial specialization for vector<T>
template <typename T>
struct X<vector<T>> {
static vector<T> _from_string(const string& str) {
// stuff that should be done only if the template parameter if a vector of something
}
};
// helper function template
template <typename TResult>
inline TResult _from_string(const string& str) {
return X<TResult>::_from_string(str);
}
然后
auto x1 = _from_string<unsigned long long>("12345");
auto x2 = _from_string<vector<int>>("{1,2,3,4,5}");
您不能部分專門化功能。
您很少應該完全專門化功能。
處理此問題的一種更好的方法是使用重載。 返回類型的重載僅需要一個額外的arg:
template<class T> struct tag_t{constexpr tag_t(){}; using type=T;};
template<class T>constexpr tag_t<T> tag{};
template <typename TResult> inline TResult _from_string(const string& str){
return _from_string( tag<TResult>, str );
}
現在,我們不再專門使用_from_string
,我們只重載了2 arg版本。
inline unsigned long long _from_string(tag_t<unsigned long long>, const string& str) {
return stoull(str);
}
以上甚至都不是模板。
template <class T, class A>
std::vector<T,A> _from_string(tag_t<std::vector<T,A>>, const string& str) {
// stuff that should be done only if the target type is a vector of something
}
以上是一個模板,但不是一個專門的模板。
作為獎勵,如果你有一個自定義類型bob
在namespace foo
,你只需要編寫_from_string( tag_t<bob>, std::string const& )
在namespace foo
,和一些被稱為“ADL”會自動找到它最案件。
使用標簽進行的基於重載的分派非常簡單明了,可讓您自定義相關命名空間中的內容。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.