2014-09-25 163 views
1

我已經創建了用於投射字符串的模板來執行不同的數據類型,並且當數據類型是無符號字符時它有問題。將std :: string(保證數字)轉換爲無符號字符

template<class TYPE> 
bool TryParse(const std::string value, TYPE &out) 
{ 
    std::istringstream iss(value); 
    iss >> out; 

    if (iss.fail()) 
    { 
     return false; 
    } 

    return true; 
} 

的問題是istringstream會治療,而不是把它當作一個數字字符串,它認爲一個字符的第一個字符。所以如果我傳遞一個值「255」,返回的值將是'2'。

難道最好的解決方案是將out變量作爲一個無符號整型,執行操作,然後再次退回?

+1

你可以使用'boost :: lexical_cast' - 它不能解決你的具體問題,但它確實使你不會重新發明輪子。 – Chad 2014-09-25 16:15:27

+1

另外,考慮通過引用傳遞'value'。事實上,你迫使調用者無緣無故地複製字符串。 – cdhowie 2014-09-25 16:16:20

+0

爲什麼不爲「char」添加專門化? – Deduplicator 2014-09-25 16:17:56

回答

3

我建議有一個超載,特別適用於unsigned char個案,因爲您需要使用中間類型。

bool TryParse(const std::string & value, unsigned char & out) 
{ 
    std::istringstream iss(value); 
    unsigned int i; 
    iss >> i; 

    if (iss.fail()) { return false; } 

    // The less-than-min check is technically redundant because both i and out 
    // are unsigned, but it makes me feel better having it there. It will become 
    // necessary for the "signed char" overload, anyway. 
    if (i > std::numeric_limits<unsigned char>::max() || 
     i < std::numeric_limits<unsigned char>::min()) { 
      throw std::overflow_error(); 
      // Or you could "return false" instead, if that makes more sense. 
    } 

    out = static_cast<unsigned char>(i); 
    return true; 
} 

對於signed char,您可以使用幾乎相同的功能。 (只需更換每unsignedsigned。)

我不會建議在您的模板中使用中間類型,因爲您需要使用盡可能寬的類型,並且沒有任何一種類型可以工作。例如,unsigned long long intsigned long long int不兼容,反之亦然 - 並且這兩種類型都不會與floatdouble兼容。有一個直接使用請求類型的基本模板,並且有問題類型的重載(例如,char)是正確的方法。


請注意,我已經改變了value參數是常量字符串的引用,因爲這意味着,調用者不需要字符串複製無緣無故。我會建議改變你的模板功能。

+0

這是完美的,謝謝。 – JoshBramlett 2014-09-25 16:30:31

相關問題