2012-11-04 94 views
5

我想爲std :: stoi,std :: stof,std :: STOD等,如:相關函數族的通用函數(例如std :: stoi,std :: stof,std :: stod等)

// std::string -> int 
std::string str = "1000000"; 
int i = to_numeric<int>(str); 

// std::string -> long 
std::string str = "100000000000"; 
long i = to_numeric<long>(str); 

// std::string -> float 
std::string str = "10000.1"; 
float i = to_numeric<float>(str); 

但我不知道如何使局部特殊化:

template<class T> 
int to_numeric(const std::string &str, size_t *pos = 0, int base = 10) { 
    return std::stol(str, pos, base); 
}; 

template<> 
long to_numeric<long>(const std::string &str, size_t *pos, base) { 
    return std::stol(str, pos, base); 
}; 

template<> 
float to_numeric<float>(const std::string &str, size_t *pos) { 
    return std::stof(str, pos); 
}; 
// ..... 

錯誤:

to_numeric.cpp:76:79: error: default argument specified in explicit specialization [-fpermissive] 
to_numeric.cpp:76:12: error: template-id 'to_numeric<float>' for 'float to_numeric(const string&, size_t*)' does not match any template declaration 
make: *** [build] Error 1 
+3

我只是使用'boost :: lexical_cast'。 – chris

+0

我沒有提升,但我的C++ 11具有相同的功能 – Robbin

+0

由於您需要指定目標類型,爲什麼要麻煩?對於泛型函數,讓用戶傳遞一個回調來完成轉換,這可能是'std :: stoi'和family。另外,由於這不是明確的關於C++ 11的功能(你只是在實現中使用一個功能,但你也可以調用其他任何東西),所以我編輯了這些標記。 – Xeo

回答

3

您可以指定一個帶有三個參數(str,posbase)的主模板,但您只需要僅使用一個參數的函數模板來對其進行專門化。顯然,這不起作用:專業化需要匹配主模板。

功能模板的部分專業化尚未支持。如果你需要一個部分專用的函數模板,你需要間接地進行部分專業化:你將委託給一個類模板並部分專門化。類模板可能只有一個static函數。當然,在你的例子中,你不使用部分專業化,而是完全專業化。

+0

您能否提供一個簡單的例子? – Robbin

+0

@Robbin:一個簡單的例子...?修正你的代碼應該是直截了當的(添加缺少的參數,正如Joachim Pileborg指出的,給主模板返回一個'T'類型),並且使用部分專精,我不得不承認我不知道你會在哪裏想在這種情況下使用部分專業化! –

+0

對不起我的誤解,我意識到我的錯誤) – Robbin

2

首先,您必須使非模板功能完全模板化。這意味着你必須使返回類型爲T。我還建議這個非專門化的功能不會做任何超過返回的事情。 T()(因爲它不是專用的,不知道要調用哪個函數)。

繼續進行,to_numeric<float>專業化需要有相同參數作爲非專業的功能,所以你需要添加虛擬base說法。