2012-10-09 87 views
2

我要讓排除類型的字符串或字符模板排除一種類型

template <typename T> 
bool parse(T & value, const string & token){ 
    istringstream sin(token); 
    T t; 
    if(!(sin >>t)) return false; 
    char junk; 
    if(sin >>junk) return false; 
    value = t; 
    return true; 
} 

我該怎麼做一個解析函數?

+0

爲什麼?爲什麼不把它稱爲字符串或字符......要容易得多。 – Annabelle

+0

你想爲字符串和字符發生什麼?那麼char指針和數組呢? –

+0

我正在接受一個輸入,該輸入應該有一個數組序列,我將它存儲在一個數組中。然後理想情況下,應該有數字後面的字符。我需要將數字解析爲適當的類型,然後將它們存儲到模板數組中,我有其他地方。 – Painguy

回答

3

取決於你的意思是不包括類型stringchar。如果你想讓它不鏈接你可以聲明而不是類型定義專業:

template <> 
void parse<std::string>(std::string & value, const std::string& token); 

編譯器將看到的專業化,而不是生成代碼。鏈接器將失敗,因爲符號未在任何翻譯單元中定義。

第二種方法,有點複雜的是不要在鏈接時失敗,但要讓編譯器不接受這些類型的模板。這可以用SFINAE,這是在C++ 11簡單做,但如果你需要一個C++ 03解決方案,您可以谷歌或添加評論:

template <typename T, 
      typename = typename std::enable_if<!std::is_same<T,std::string> 
              && !std::is_same<T,char>>::type > 
void parse(T & t, const std::string& token) { 
// ... 
} 

(我沒有經歷過這種運行一個編譯器,所以語法可能會有點偏離,玩它)編譯器將看到模板,並且當它試圖執行T類型的替換時,由於std::enable_if<...>::type未解析爲類型,它將失敗。

在一般情況下,你可能想要的是提供執行parse特定版本的不同過載和優先:

void parse(std::string& v, const std::string& token) { 
    v = token; 
} 

請注意,這不是一個模板,但常規的函數。當模板函數的參數是完美匹配時,非模板函數將比模板函數更好匹配。

+0

您的建議有效。我想我會去重載功能。這是一個更易讀的解決方案。 – Painguy

0

模板應在 大衛·羅德里格斯的方法聲明如下(與返回類型的函數):

template <template T, typename std::enable_if<!std::is_same<T,std::string>::value>::type* = nullptr > 
T func(T x){} 

對於多個條件:

template <template T, typename std::enable_if<!std::is_same<T,std::string>::value &&!std::is_same<T,int>::value>::type* = nullptr > 
T func(T x){} 

對於函數沒有返回類型:

template <template T> 
typename std::enable_if<!std::is_same<T,std::string>::value>::type 
func(T x){} 

對於多個條件:

template <template T> 
typename std::enable_if<!std::is_same<T,std::string>::value &&!std::is_same<T,int>::value>::type 
func(T x){} 

不要忘了包括#include <type_traits>