C++ Boost Variant示例超詳細講解
一、提要
Boost.Variant 提供了一個類似于 union 的名為 boost::variant 的類。您可以將不同類型的值存儲在 boost::variant 變量中。在任何時候只能存儲一個值。分配新值時,舊值將被覆蓋。但是,新值的類型可能與舊值不同。唯一的要求是這些類型必須作為模板參數(shù)傳遞給 boost::variant,這樣它們才能為 boost::variant 變量所知。
boost::variant 支持任何類型。例如,可以將 std::string 存儲在 boost::variant 變量中——這在 C++11 之前使用聯(lián)合是不可能的。在 C++11 中,對聯(lián)合的要求被放寬了?,F(xiàn)在聯(lián)合可以包含一個 std::string。因為 std::string 必須使用placement new 進行初始化,并且必須通過顯式調用析構函數(shù)來銷毀,所以使用 boost::variant 仍然有意義,即使在 C++11 開發(fā)環(huán)境中也是如此。
二、示例
示例 24.1。使用 boost::variant
#include <boost/variant.hpp> #include <string> int main() { boost::variant<double, char, std::string> v; v = 3.14; v = 'A'; v = "Boost"; }
boost::variant 在 boost/variant.hpp 中定義。因為 boost::variant 是一個模板,所以必須至少指定一個參數(shù)。一個或多個模板參數(shù)指定支持的類??型。在示例 24.1 中,v 可以存儲類型為 double、char 或 std::string 的值。但是,如果您嘗試將 int 類型的值分配給 v,則生成的代碼將無法編譯。
示例 24.2。使用 boost::get() 訪問 boost::variant 中的值
#include <boost/variant.hpp> #include <string> #include <iostream> int main() { boost::variant<double, char, std::string> v; v = 3.14; std::cout << boost::get<double>(v) << '\n'; v = 'A'; std::cout << boost::get<char>(v) << '\n'; v = "Boost"; std::cout << boost::get<std::string>(v) << '\n'; }
要顯示 v 的存儲值,請使用獨立函數(shù) boost::get()(參見示例 24.2)。
boost::get() 期望對應變量的有效類型之一作為模板參數(shù)。指定無效類型將導致運行時錯誤,因為類型驗證不會在編譯時進行。
boost::variant 類型的變量可以寫入標準輸出流等流,從而繞過運行時錯誤的風險(參見示例 24.3)。
示例 24.3。在流上直接輸出 boost::variant
#include <boost/variant.hpp> #include <string> #include <iostream> int main() { boost::variant<double, char, std::string> v; v = 3.14; std::cout << v << '\n'; v = 'A'; std::cout << v << '\n'; v = "Boost"; std::cout << v << '\n'; }
對于類型安全的訪問,Boost.Variant 提供了一個名為 boost::apply_visitor() 的函數(shù)。
示例 24.4。使用訪問者來提升::variant
#include <boost/variant.hpp> #include <string> #include <iostream> struct output : public boost::static_visitor<> { void operator()(double d) const { std::cout << d << '\n'; } void operator()(char c) const { std::cout << c << '\n'; } void operator()(std::string s) const { std::cout << s << '\n'; } }; int main() { boost::variant<double, char, std::string> v; v = 3.14; boost::apply_visitor(output{}, v); v = 'A'; boost::apply_visitor(output{}, v); v = "Boost"; boost::apply_visitor(output{}, v); }
作為其第一個參數(shù),boost::apply_visitor() 期望從 boost::static_visitor 派生的類的對象。此類必須為它所作用的 boost::variant 變量使用的每種類型重載 operator()。因此,在示例 24.4 中,運算符重載了 3 次,因為 v 支持 double、char 和 std::string 類型。
boost::static_visitor 是一個模板。 operator() 的返回值類型必須指定為模板參數(shù)。如果運算符沒有返回值,則不需要模板參數(shù),如示例中所示。
傳遞給 boost::apply_visitor() 的第二個參數(shù)是一個 boost::variant 變量。
boost::apply_visitor() 自動為第一個參數(shù)調用 operator() ,該參數(shù)與當前存儲在第二個參數(shù)中的值的類型相匹配。這意味著每次調用 boost::apply_visitor() 時,示例程序都會使用不同的重載運算符——首先是用于 double 的運算符,然后是用于 char 的運算符,最后是用于 std::string 的運算符。
boost::apply_visitor() 的優(yōu)點不僅在于自動調用正確的運算符。此外,boost::apply_visitor() 確保為 boost::variant 變量支持的每種類型都提供了重載運算符。如果未定義三個重載運算符之一,則無法編譯代碼。
如果重載的運算符在功能上是等效的,則可以使用模板簡化代碼(參見示例 24.5)。
示例 24.5。使用帶有 boost::variant 函數(shù)模板的訪問者
#include <boost/variant.hpp> #include <string> #include <iostream> struct output : public boost::static_visitor<> { template <typename T> void operator()(T t) const { std::cout << t << '\n'; } }; int main() { boost::variant<double, char, std::string> v; v = 3.14; boost::apply_visitor(output{}, v); v = 'A'; boost::apply_visitor(output{}, v); v = "Boost"; boost::apply_visitor(output{}, v); }
因為 boost::apply_visitor() 確保了編譯時代碼的正確性,所以應該優(yōu)先于 boost::get()。
到此這篇關于C++ Boost Variant示例超詳細講解的文章就介紹到這了,更多相關C++ Boost Variant內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
C語言超詳細講解數(shù)據結構中雙向帶頭循環(huán)鏈表
帶頭雙向循環(huán)鏈表:結構最復雜,一般用在單獨存儲數(shù)據。實際中使用的鏈表數(shù)據結構,都是帶頭雙向循環(huán)鏈表。另外這個結構雖然結構復雜,但是使用代碼實現(xiàn)以后會發(fā)現(xiàn)結構會帶來很多優(yōu)勢,實現(xiàn)反而簡單2022-04-04C++使用TinyXML2實現(xiàn)解析和生成XML數(shù)據
TinyXML2是一個輕量級的、開源的C++庫,專門用于解析和生成XML文檔,本文主要為大家介紹了如何使用TinyXML2實現(xiàn)解析和生成XML數(shù)據,需要的可以參考下2024-04-04VC++ 使用 _access函數(shù)判斷文件或文件夾是否存在
這篇文章主要介紹了VC++ 使用 _access函數(shù)判斷文件或文件夾是否存在的相關資料,需要的朋友可以參考下2015-10-10