Boost的轉換函式(二)

來源:互聯網
上載者:User

原文地址:http://www.cnblogs.com/TianFang/archive/2008/09/29/1301880.html

Boost的轉換函式(二)
  • boost::numeric_cast

在c++中,我們經常需要把不同類型的數字互相轉換,如將一個數字在long和short之間轉換。但由於各數位精度不同,當一個數字從"大"類型到"小"類型就可能導致轉換失敗,如下所示:

long n1 = 99999999;
short n2 = static_cast<short>(n1);

對於如上轉換,n2得到的是一個負數,顯然這個不是我們所期望的,並且這種運行時的錯誤是很難檢測的,一旦使用了這個錯誤的轉換後的資料,後果不堪設想。

boost::numeric_cast可以協助我們解決這一問題,對於上面的轉換,boost::numeric_cast會拋出一個boost:: bad_numeric_cast這個異常對象。從而保證轉換後值的有效性。上述代碼可以改寫為如下:

try
{
    long n1 = 99999999;
    short n2 = boost::numeric_cast<short>(n1);
}
catch(boost::bad_numeric_cast&)

    std::cout<<"The conversion failed"<<std::endl; 

numeric_cast是如何知道這樣的數字轉換失敗的呢?numeric_cast合理的應用了std::numeric_limits<>,而std::numeric_limits<>就是內建數字類型的type_tratis。當然也可以將自己定義的數字抽象類別型添加到std::numeric_limits<>的特化版本中,這樣numeric_cast就可以作用於自訂的類型了。由於相對複雜點,本文是介紹其功能和用法,就不分析其源碼了,感興趣的朋友可以參看boost文檔和代碼。

對於numeric_cast的使用也是有些要求的。

  1. 源類型和目標類型必須都是可拷貝構造的
  2. 源類型和目標類型必須都是數字型類型。也就是被std::numeric_limits<>::is_specialized的特化定義為true
  3. 源類型必須能被static_cast轉換為目標類型

其實對我們用的系統內建的數字來說,這幾條都不是限制,只有我們在需要通過它轉換自訂的資料類型時,才需要注意,否則編譯不通過(其實這個錯誤還比較好發現和解決)。

  • boost::lexical_cast

在C/C++程式開發中,往往需要將數字型對象的值轉換為字元文字格式設定,或反之操作。雖然C語言就提供了不少系統函數來進行這種操作,如scanf、atoi等。這些函數小巧簡潔,使用很方便,但缺少擴充性。在std中引入了stringstream來以一個通用的方式實現各種轉換,但缺少對錯誤轉換的檢測。而boost::lexical_cast是在stringstream上的一個擴充,增加了對錯誤的類型轉換的檢測:

#include <string>
#include <iostream>
#include <boost/lexical_cast.hpp>

using namespace std;

int main()
{     
    try
    { 
        int i = 100; 
        string str = boost::lexical_cast<string>(i); 
        cout<<"The string is:"<<str<<endl; 
        str = "error"; 
        i = boost::lexical_cast<int>(str); 
    } 
    catch(boost::bad_lexical_cast& exobj)
    { 
        cout<<"Convert err:"<<endl; 
        cout<<exobj.what()<<endl; 
    } 
}

在上述轉換中,第二個轉換從"err"到int的轉換是失敗的,會拋出一個boost::bad_lexical_cast的異常,從而能協助我們構造更安全穩定的程式。

boost::lexical_cast內部實現其實也是一個stringstream的封裝,其函數簡化如下:

template<typename Target,typename Source> 
Target lexical_cast(Source arg){ 
    detail::lexical_stream<Target,Source> interpreter; 
    Target result; 
    if(!(interpreter<<arg && interpreter>>result)) 
        throw_exception(bad_lexical_cast(typeid(Target),typeid(Source))); 
    return result; 

其中lexical_stream<>對字串流做了一系列的封裝,主要提供了operator<<(Source)和operator>>(Target)操作,用於判斷操作是否成功。

  • boost::numeric_cast

在c++中,我們經常需要把不同類型的數字互相轉換,如將一個數字在long和short之間轉換。但由於各數位精度不同,當一個數字從"大"類型到"小"類型就可能導致轉換失敗,如下所示:

long n1 = 99999999;
short n2 = static_cast<short>(n1);

對於如上轉換,n2得到的是一個負數,顯然這個不是我們所期望的,並且這種運行時的錯誤是很難檢測的,一旦使用了這個錯誤的轉換後的資料,後果不堪設想。

boost::numeric_cast可以協助我們解決這一問題,對於上面的轉換,boost::numeric_cast會拋出一個boost:: bad_numeric_cast這個異常對象。從而保證轉換後值的有效性。上述代碼可以改寫為如下:

try
{
    long n1 = 99999999;
    short n2 = boost::numeric_cast<short>(n1);
}
catch(boost::bad_numeric_cast&)

    std::cout<<"The conversion failed"<<std::endl; 

numeric_cast是如何知道這樣的數字轉換失敗的呢?numeric_cast合理的應用了std::numeric_limits<>,而std::numeric_limits<>就是內建數字類型的type_tratis。當然也可以將自己定義的數字抽象類別型添加到std::numeric_limits<>的特化版本中,這樣numeric_cast就可以作用於自訂的類型了。由於相對複雜點,本文是介紹其功能和用法,就不分析其源碼了,感興趣的朋友可以參看boost文檔和代碼。

對於numeric_cast的使用也是有些要求的。

  1. 源類型和目標類型必須都是可拷貝構造的
  2. 源類型和目標類型必須都是數字型類型。也就是被std::numeric_limits<>::is_specialized的特化定義為true
  3. 源類型必須能被static_cast轉換為目標類型

其實對我們用的系統內建的數字來說,這幾條都不是限制,只有我們在需要通過它轉換自訂的資料類型時,才需要注意,否則編譯不通過(其實這個錯誤還比較好發現和解決)。

  • boost::lexical_cast

在C/C++程式開發中,往往需要將數字型對象的值轉換為字元文字格式設定,或反之操作。雖然C語言就提供了不少系統函數來進行這種操作,如scanf、atoi等。這些函數小巧簡潔,使用很方便,但缺少擴充性。在std中引入了stringstream來以一個通用的方式實現各種轉換,但缺少對錯誤轉換的檢測。而boost::lexical_cast是在stringstream上的一個擴充,增加了對錯誤的類型轉換的檢測:

#include <string>
#include <iostream>
#include <boost/lexical_cast.hpp>

using namespace std;

int main()
{     
    try
    { 
        int i = 100; 
        string str = boost::lexical_cast<string>(i); 
        cout<<"The string is:"<<str<<endl; 
        str = "error"; 
        i = boost::lexical_cast<int>(str); 
    } 
    catch(boost::bad_lexical_cast& exobj)
    { 
        cout<<"Convert err:"<<endl; 
        cout<<exobj.what()<<endl; 
    } 
}

在上述轉換中,第二個轉換從"err"到int的轉換是失敗的,會拋出一個boost::bad_lexical_cast的異常,從而能協助我們構造更安全穩定的程式。

boost::lexical_cast內部實現其實也是一個stringstream的封裝,其函數簡化如下:

template<typename Target,typename Source> 
Target lexical_cast(Source arg){ 
    detail::lexical_stream<Target,Source> interpreter; 
    Target result; 
    if(!(interpreter<<arg && interpreter>>result)) 
        throw_exception(bad_lexical_cast(typeid(Target),typeid(Source))); 
    return result; 

其中lexical_stream<>對字串流做了一系列的封裝,主要提供了operator<<(Source)和operator>>(Target)操作,用於判斷操作是否成功。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.