C++boost库之variant使用
2017-06-21 18:56
323 查看
Variant库包含一个不同于union的泛型类,用于在存储和操作来自于不同类型的对象。这个库的一个特点是支持类型安全的访问,减少了不同数据类型的类型转换代码的共同问题。
通过boost的variant类型,variant类型可以表示任意一种类型和any类型有些相似,但还是有些区别,比如说variant支持的类型需提前定义,而any类型不需要,获取any类型的值需要给出原始类型,然而variant类型支持多种方式访问,其中一种就是通过访问者模式来访问,是不需要给出原始类型的,下面将浅谈variant的几种访问方式:
使用boost::get来访问,需要给出原始类型,并且这样做不安全,若类型错误,程序将会抛出异常。
使用RTTI技术可以避免类型访问错误而程序异常的情况,但是这样做有点不优雅,每增加一个类型,都需要修改if-else结构,并且使用RTTI会对程序性能有一定影响。
使用该模式,需要定义一个类并继承于boost::static_visitor,在类里面需要重载
将
通过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 << boost::get<int>(v) << std::endl; } else if (v.type() == typeid(std::string)) { std::cout << boost::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支持多少类型。
相关文章推荐
- C++boost库之variant使用
- Boost库之tuple、any和variant的使用
- C++使用VARIANT实现二维数组的操作
- C++“准”标准库Boost学习指南-variant的使用
- C++boost库之assign使用(一)
- 推荐使用C++ TR1和boost库
- 如何Visual Studio环境使用 C++ Boost库,详细步骤
- c++下boost库的使用配置
- 关于C++ Boost库的使用
- C++“准”标准库Boost学习指南-variant的使用
- Google C++ Style中允许使用的Boost库(1) - 程序即人生 - 博客频道 - CSDN.NET
- C++使用VARIANT实现二维数组的操作
- c++中使用boost::regex(由于标准库中版本过低,导致不支持多行,需手动编译添加最新版的boost库)
- C++开发--在Visual Studio2013中使用boost库
- Base64系列第三篇 C/C++中使用Base64编码解码(使用boost库)
- Google C++ Style中允许使用的Boost库(1)
- 使用C++和Boost库写一个自己的脚本引擎
- C++ boost库的ptime的使用
- c/c++ 使用boost库实现的一个简单判断字符串编码的方法
- C++使用VARIANT实现二维数组的操作、怎么使用COleSafeArray实现二维数组将字符串写入excel