簡體   English   中英

特定模板類型的功能專業化

[英]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
}

以上是一個模板,但不是一個專門的模板。

作為獎勵,如果你有一個自定義類型bobnamespace foo ,你只需要編寫_from_string( tag_t<bob>, std::string const& )namespace foo ,和一些被稱為“ADL”會自動找到它最案件。

使用標簽進行的基於重載的分派非常簡單明了,可讓您自定義相關命名空間中的內容。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM