淺談boost.variant的幾種訪問方式

wrut7785 8年前發布 | 29K 次閱讀 Boost C/C++開發

前言

variant類型在C++14并沒有加入,在 cppreference 網站上可以看到該類型將會在C++17加入,若想在不支持C++17的編譯器上使用variant類型,我們可以通過boost的variant類型,variant類型可以表示任意一種類型和any類型有些相似,但還是有些區別,比如說variant支持的類型需提前定義,而any類型不需要,獲取any類型的值需要給出原始類型,然而variant類型支持多種方式訪問,其中一種就是通過訪問者模式來訪問,是不需要給出原始類型的,下面將淺談variant的幾種訪問方式。

使用boost::get

boost::variant<int, std::string> v;
v = "Hello world";
std::cout << boost::get<std::string>(v) << std::endl;

使用boost::get來訪問,需要給出原始類型,并且這樣做不安全,若類型錯誤,程序將會拋出異常。

使用RTTI

void var_print(boost::variant<int, std::string>& v)  
{  
    if (v.type() == typeid(int))  
    {  
        std::cout << get<int>(v) << std::endl;  
    }
    else if (v.type() == typeid(std::string))  
    {  
        std::cout << get<std::string>(v) << std::endl;  
    }  
    // Else do nothing
}  
int main()  
{  
    boost::variant<int, std::string> v;
    v = "Hello world";  
    var_print(v);
    return 0;
}

使用RTTI技術可以避免類型訪問錯誤而程序異常的情況,但是這樣做有點不優雅,每增加一個類型,都需要修改if-else結構,并且使用RTTI會對程序性能有一定影響。

使用訪問者模式

class var_visitor : public boost::static_visitor<void>
{
public:
    void operator()(int& i) const
    {
        std::cout << i << std::endl;
    }

    void operator()(std::string& str) const
    {
        std::cout << str << std::endl;
    }
};
int main()  
{  
    boost::variant<int, std::string> v;
    v = "Hello world";  
    boost::apply_visitor(var_visitor(), v);
    return 0;
}

使用該模式,需要定義一個類并繼承于boost::static_visitor,在類里面需要重載 () 操作符,通過boost::apply_visitor來訪問原始類型的值,這樣做還是有些繁瑣,每增加一個類型,都需要在var_visitor里面增加一個函數,但比使用RTTI里面的修改if-else結構好得多,因為使用訪問者模式至少是遵循開放-封閉原則的,即對寫開放,對修改封閉。

使用模板函數

class var_visitor : public boost::static_visitor<void>
{
public:
    template<typename T>
    void operator()(T& i) const
    {
        std::cout << i << std::endl;
    }
};
int main()  
{  
    boost::variant<int, std::string> v;
    v = "Hello world";  
    boost::apply_visitor(var_visitor(), v);
    return 0;
}

將 operator() 改成了模板函數的好處就是不用關心variant支持多少類型。

 

 

來自:http://www.cnblogs.com/highway-9/p/6002306.html

 

 本文由用戶 wrut7785 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!