我有一個包含字串成員變數的類,并試圖撰寫一個模板函式,使我能夠將字串轉換為另一種型別。作為一個簡化的例子,在沒有模板的情況下,我將這樣做。
struct A {
std::vector<std::string> tokens;
};
void Test(constA& a){
//獲得最終的令牌值為一個int,或默認為42.。
int i = a.tokens.empty() ? 42 : std::stoi(*a.tokens.rbegin() 。)
然而這在很多地方寫起來都很繁瑣,因為我想得到最終的標記并對其進行決議,所以我寫了下面的內容來輔助。
struct A {
std::vector<std::string> tokens。
const string& GetLast(const string& defaul = "" ){
return tokens.empty() ? defaul : *tokens.rbegin() 。
}
int GetLast(int defaul){
return tokens.empty() ? defaul : std::stoi(*tokens.rbegin() )。)
}
float GetLast(float defaul){
return tokens.empty() ? defaul : std::stof(*tokens.rbegin() ) 。
}
};
void Test(constA& a){
int i = a.GetLast(42)。
}
這樣做很好,但它似乎只是要求做成一個模板,并允許轉換為任何種類的型別,只要提供一個轉換函式。然而,我似乎找不到一個可以作業的通用解決方案。以下是我能想到的最接近作業的方法,但我經常收到編譯器錯誤,說模板型別不能被推斷。
template <typename T,typename Converter,typename。Args>
T GetLastAs(T defaul, Args ...args)
{
return tokens.empty() ? defaul : Converter(*tokens.rbegin(), args... )。
使用方法 a.GetLastAs<float, std::stof> (42.0f)
這個問題有沒有一個通用的解決方案,還是說這只是我一廂情愿的想法?
編輯:
template< class Converter, typename T, typename. .Args>
T GetLast(T defaul, Args ...args, Converter f = Converter())/span> const
{
return tokens.empty() ? defaul : f(*tokens.rbegin(), args...) 。
用一個轉換器結構定義為 struct ToInt { int operator()(const std::string& str) { return std::stoi(str); };/code> };
以及a.GetLast<ToInt>(42);或a.GetLast(42, ToInt());的用法。
但是我不能將ToInt的用法替換為std::stoi,我相信原因可能是stoi有一個多載,可以接受wstring而不是string,而GetLast方法不能找出要使用哪個多載。我不知道是否有可能指定使用哪個多載。
uj5u.com熱心網友回復:
你可以使用一個字串流來提取默認可構造型別的值,像這樣:
template <typename T>
T GetAs(const std::string& s) {
std::stringstream ss{s};
T t。
ss >> t。
return t。
}
int main() {
std::string s{"3.5"/span>}。
std::cout << GetAs<int> (s) << "
"。
std::cout << GetAs<double> (s) << "
"。
std::cout << GetAs<std::string> (s) << "
"。
}
我把默認值和字串是矢量元素的事實放在一邊,因為這對解決方案來說并不重要。
uj5u.com熱心網友回復:
你可以將字串放入一個std::istringstream中,并使用>>運算子將其值提取到一個變數中。
如在
T value{};
std::istringstream{ string_to_convert } >> value。
當然,這需要 或者對于更通用的轉換(如果你正在使用Boost)Boost convert。它可以處理不同的數字基數。
標籤:T是可默認構建的,以及有一個為T定義的>>/code>運算子。
IIRC這就是Boost詞法鑄造的作業方式(或者至少曾經是這樣)。如果你已經在你的專案中使用了Boost,我建議你使用它的詞法轉換庫而不是自己制作。
