• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Khan's Notebook GCC/GNU/Linux Delphi/Window Java/Anywhere

            路漫漫,長修遠(yuǎn),我們不能沒有錢
            隨筆 - 173, 文章 - 0, 評論 - 257, 引用 - 0
            數(shù)據(jù)加載中……

            boost的lexical_cast --數(shù)據(jù)類型轉(zhuǎn)

            注:轉(zhuǎn)載請保證文章完整性

            一、介紹

            lexical_cast是boost中一個非常有用,常用,好用的庫,我現(xiàn)在的小數(shù)據(jù)轉(zhuǎn)換用的都是lexical_cast lexical_cast最大的特點(diǎn)是安全,包括長度安全,類型安全。 下面我來介紹下lexical_cast的基本使用方法。

            Target lexical_cast(Source arg)
            

            例如:

            #include <boost/lexical_cast.hpp>           //lexical_cast的頭文件
            
            using namespace std;                        //stl的域
            using namespace boost;                      //boost的域
            
            int main() {
                const double PI = 3.1415926535;
                string str;
                str = lexical_cast<string>(PI);
                cout << str; 
                return 0;
            }
            

            非常容易吧,簡單也是他的優(yōu)勢之一。

            二、異常

            lexical_cast在執(zhí)行失敗時(shí)會拋出異常bad_lexical_cast 上面的例子改為:

            #include <boost/lexical_cast.hpp>           //lexical_cast的頭文件
            
            using namespace std;                        //stl的域
            using namespace boost;                      //boost的域
            
            int main() {
                try {
                    string str = "3.1415926535";
                    double PI = lexical_cast<double>(str);
                    cout << PI; 
                    return 0;
                } catch( bad_lexical_cast& E ) {
                    cout << E.what() << endl;
                }
            }
            

            當(dāng)str為ABCD時(shí), 無法轉(zhuǎn)成PI拋出異常 輸出

            bad lexical cast: source type value could not be interpreted as target
            

            三、一個小例子

            為了加深大加理解 下面使用lexical_cast實(shí)現(xiàn)一個簡單的文本輸入是否為指定類型的小程序

            #include <boost/lexical_cast.hpp>
            #include <iostream>
            
            using namespace std;                       //stl的域
            using namespace boost;                     //boost的域
            
            template<typename _T, typename _R>
            bool isElement(_R r) {
                try {
                    lexical_cast<_T>(r);                
                    return true;                        //轉(zhuǎn)換成功
                } catch(...) {
                    return false;
                }
            }
            
            int main() {
                try {
                    if( isElement<double>("3.14d159") )
                        cout << "YES" << endl;
                    else
                        cout << "NO" << endl;
            
                } catch( bad_lexical_cast& E ) {
                    cout << E.what() << endl;
                }
                return 0;    
            }
            

            測試結(jié)果:

            測試:isElement<double>("3.14d159") 輸出:NO
            測試:isElement<string>("3.14d159") 輸出:YES
            測試:isElement<long>("314159")     輸出:YES
            測試:isElement<long>("31.4159")    輸出:NO
            測試:isElement<char>("314159")     輸出:NO
            

            四、源碼分析

            #ifdef BOOST_NO_STRINGSTREAM // 我們知道stringstream和strstream分別
                                         // 是string和char*結(jié)構(gòu), lexical_cast考慮很全面的。
                #include <strstream>
            #else
                #include <sstream>
            #endif
            
            // bad_lexical_cast是bad_cast的繼承,所以很標(biāo)準(zhǔn),支持和擴(kuò)充性都很好。
            class bad_lexical_cast : public std::bad_cast {
                public:
                    bad_lexical_cast() :
                        source( &typeid(void) ), target( &typeid(void) )
                    {
                    }
            
                    bad_lexical_cast( const std::type_info &s, const std::type_info &t ) :
                        source(&s), target(&t)
                    {
                    }
            
                    //提供了兩個返回type_info的函數(shù),為我們跟蹤調(diào)試類形轉(zhuǎn)換起到很好的做用。
                    const std::type_info &source_type() const 
                    {
                        return *source;
                    }
            
                    const std::type_info &target_type() const
                    {
                        return *target;
                    }
            
                    virtual const char *what() const throw()
                    {
                        return "bad lexical cast: "
                               "source type value could not be interpreted as target";
                    }
            
                    virtual ~bad_lexical_cast() throw()
                    {
                    }
                private:
                    const std::type_info *source;
                    const std::type_info *target;
                };
            

            type_info的具體用法是:E.source_type().name()就可能到類型名。

            核心轉(zhuǎn)換部分,用的是留的概念,從流內(nèi)數(shù)據(jù)的剩余情況與流轉(zhuǎn)換成功與否情況來判斷操作是否成功。在不加域時(shí)這里就像一個黑盒子。

                    bool operator<<(const Source &input)
                    {
                        return !(stream << input).fail();
                    }
            
                    template<typename InputStreamable>
                    bool operator>>(InputStreamable &output)
                    {
                        return !is_pointer<InputStreamable>::value &&
                                stream >> output &&
                                (stream >> std::ws).eof();
                    }
            
                    bool operator>>(std::string &output)
                    {
                        #if defined(BOOST_NO_STRINGSTREAM)
                        stream << '\0';
                        #endif
                        output = stream.str();
                        return true;
                    }
            

            僅提供該入口,具體實(shí)現(xiàn)被封在detail域里面。

                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;
                }
            

            最后, 我們可以發(fā)現(xiàn)

            bad_lexical_cast(typeid(Target), typeid(Source)
            

            與上面

            bad_lexical_cast(const std::type_info &s, const std::type_info &t) 
                    :source(&s), target(&t)
            

            之間的區(qū)別,在我看來是寫倒了,不過不影響,也算是個不算bug的bug

            五、總結(jié)

            lexical_cast是強(qiáng)大的,但不是萬能的,但在很多情況下他有著獨(dú)特的優(yōu)點(diǎn),安全方便快捷!!!

            posted on 2017-10-14 16:26 Khan 閱讀(809) 評論(0)  編輯 收藏 引用 所屬分類: GCC/G++跨平臺開發(fā)

            国产巨作麻豆欧美亚洲综合久久| 无码国内精品久久人妻蜜桃 | 久久精品国产亚洲AV蜜臀色欲 | 91精品观看91久久久久久 | 99久久久精品免费观看国产| 国产99精品久久| 久久黄视频| 久久久亚洲欧洲日产国码aⅴ| 色噜噜狠狠先锋影音久久| 伊人久久大香线蕉综合热线| 久久人人爽人人爽人人AV东京热| 热久久国产精品| 性欧美丰满熟妇XXXX性久久久| 亚洲乱亚洲乱淫久久| 欧美黑人又粗又大久久久| 青春久久| 观看 国产综合久久久久鬼色 欧美 亚洲 一区二区 | 国产精品久久久久影院嫩草| 香港aa三级久久三级老师2021国产三级精品三级在 | 影音先锋女人AV鲁色资源网久久| 99久久无码一区人妻| 久久久久亚洲av无码专区导航 | 伊人色综合久久天天人手人婷| 中文精品久久久久国产网址| 久久AV高潮AV无码AV| 久久国产视频网| 94久久国产乱子伦精品免费| 99久久婷婷免费国产综合精品| 亚洲中文字幕久久精品无码APP| 亚洲国产精品狼友中文久久久| AAA级久久久精品无码区| 国产精品久久久久无码av| 久久国产免费观看精品3| 久久精品中文騷妇女内射| 亚洲AV无码一区东京热久久| 大香伊人久久精品一区二区| 天天影视色香欲综合久久| 亚洲国产成人精品无码久久久久久综合 | 日本一区精品久久久久影院| 久久99国产精品一区二区| 国产精品久久99|