boost any库
转:
原理
c++是一个强类型的语言,要实现一个万能类型可以考虑用void*来保存数据,然后用类型转换进行操作,如:
class MyAny{
MyAny(void* input):content_(input){
}
template<typename T>
T any_cast(){return *static_cast<T*>(content_)}
private:
void* content_;
}
但是这样的写法有一个明显的缺点就是类型不安全。
显然我们可以用template来改进我们的程序:
template<typename T>
class MyAny{
MyAny(T input):content_(input){
}
T any_cast(){return content_;}
private:
T content_;
}
但是这样我们好像就没有解决问题:vector<myany> 好吧,这里就写不下去了。
为了能写下如下的代码:
vector<MyAny> items;
items.push_bacck(1);
items.push_bacck(2.0);
我们需要我们的万能类型有如下的行为:
- 对外是一个一般的类,使用者压入参数的时候不应该关心类型
- 它只是一个中间层,具体保存数据的应该是一个模板类(Holder)
- 必须要能有方法支持任意类型的输入和输出为任意类型
实现
我们可以通过添加一个中间层来解决任何问题。
在boost::any中, 通过两个中间层来达成我们上面的目标, 类any作为对外的接口层,承担以模板作为参数并提供必要的对外方法。
类placeholder作为接口类,让any使用。而holder是一个模板类作为类placeholder的实现者, 这样就避免的any对泛型参数的要求(能自动推到导出来)。
(为什么要让Holder继承IHolder,原因是为了让Any避开泛型)
我这里模仿了相关的实现,其代码结构应该是这样的:
class Any
{
public:
Any() :holder_(nullptr){}
template<typename ValueType>
Any(const ValueType& val)
: holder_(new Holder<ValueType>(val)){
}
private:
IHolder* holder_;
};
struct IHolder{
}
template<typename ValueType>
class Holder : public IHolder{
public:
Holder(const ValueType& val) : value_(val){
}
}
public:
ValueType value_;
}
其中Holder提供了具体的数据存储服务,而 Any提供了对外的接口能力。
其中Holder必须提供两个方法:
mb_interface IHolder{
virtual ~IHolder(){}
virtual const std::type_info& type() const = 0;
virtual IHolder* clone() const = 0;
};
- type()提供了查询类型的能力
- clone()提供了产生数据的能力
在 Any中, 提供了以下几个个接口:
bool empty(){
return !holder_;
}
const std::type_info& type() const {
return holder_ ? holder_->type() : typeid(void);
}
Any& operator=(Any rhs){
return swap(rhs);
}
template<typename ValueType>
Any& operator=(const ValueType& val){
return Any(val).swap(*this);
}
判断是否为空,查询类型操作,赋值操作
当然必须还有最重要的any_cast操作,我们看其实现:
template<typename ValueType>
ValueType* anyCast(Any* val){
return (val && val->type() == typeid(ValueType))
? &static_cast<Holder<ValueType>*>(val->getHolder())->value_ : 0;
}
template<typename ValueType>
ValueType anyCast(Any& val){
ValueType* rtn = anyCast<ValueType>(&val);
if (!rtn)boost::throw_exception(badAnyCast());
return *rtn;
}
果然好简单。呵呵~~~
最后添上单元测试,整个代码就完善了:
mb::Any testInt(10);
mb::Any testDouble(10.0);
mb::Any testInt2(testInt);
EXPECT_EQ(testInt.empty(), false);
EXPECT_EQ(std::string(testDouble.type().name()), "double");
EXPECT_EQ(std::string(testInt2.type().name()), "int");
int val = mb::anyCast<int>(testInt);
EXPECT_EQ(val, 10);
总结
boost any库的更多相关文章
- 如何在WINDOWS下编译BOOST C++库 .
如何在WINDOWS下编译BOOST C++库 cheungmine 2008-6-25 写出来,怕自己以后忘记了,也为初学者参考.使用VC8.0和boost1.35.0. 1)下载boost ...
- Windows下如何使用BOOST C++库 .
Windows下如何使用BOOST C++库 我采用的是VC8.0和boost_1_35_0.自己重新编译boost当然可以,但是我使用了 http://www.boostpro.com/produc ...
- Boost线程库学习笔记
一.创建一个线程 创建线程 boost::thread myThread(threadFun); 需要注意的是:参数可以是函数对象或者函数指针.并且这个函数无参数,并返回void类型. 当一个thre ...
- Boost正则表达式库regex常用search和match示例 - 编程语言 - 开发者第2241727个问答
Boost正则表达式库regex常用search和match示例 - 编程语言 - 开发者第2241727个问答 Boost正则表达式库regex常用search和match示例 发表回复 Boo ...
- Boost::thread库的使用
阅读对象 本文假设读者有几下Skills [1]在C++中至少使用过一种多线程开发库,有Mutex和Lock的概念. [2]熟悉C++开发,在开发工具中,能够编译.设置boost::thread库. ...
- 一起学习Boost标准库--Boost.StringAlgorithms库
概述 在未使用Boost库时,使用STL的std::string处理一些字符串时,总是不顺手,特别是当用了C#/Python等语言后trim/split总要封装一个方法来处理.如果没有形成自己的com ...
- 一起学习Boost标准库--Boost.texical_cast&format库
今天接续介绍有关字符串表示相关的两个boost库: lexical_cast 将数值转换成字符串 format 字符串输出格式化 首先,介绍下lexical_cast ,闻其名,知其意.类似C中的at ...
- [boost] : test库
最小化的测试套件minimal_test test库提供一个最小化的测试套件minimal_test, 类似lightweight_test适合入门级测试. 需要包含文件文#include <b ...
- Boost C++ 库 中文教程(全)
Boost C++ 库 目录 第 1 章 简介 第 2 章 智能指针 第 3 章 函数对象 第 4 章 事件处理 第 5 章 字符串处理 第 6 章 多线程 第 7 章 异步输入输出 第 8 章 进程 ...
- UDF——处理二维网格的利器:Boost.Geometry库
本文编译工具:VC++ UDF Studio 该插件可以直接在Visual Studio中一键编译.加载.调试UDF源码,极大提高编写排错效率,且支持C++,MFC,Windows API和第三方库, ...
随机推荐
- acm数学(待续)
意图写出http://www.cnblogs.com/kuangbin/archive/2012/08/28/2661066.html这个东西的完善版. 1.置换,置换的运算 poj 2369 Per ...
- python netwokx环境搭建
用的python2.7 myeclipse离线安装pydev http://my.oschina.net/iuranus/blog/281978 安装pip networkx http://www.t ...
- 【Cocos2d-x游戏开发】细数Cocos2d-x开发中那些常用的C++11知识
自从Cocos2d-x3.0开始,Cocos2dx就正式的使用了C++11标准.C++11简洁方便的特性使程序的可拓展性和可维护性大大提高,也提高了代码的书写速度. 下面我们就来一起学习一下Cocos ...
- 如何將ViewData裡包含的Html輸出(MVC)
如何將ViewData裡包含的Html輸出(MVC) 默認輸入ViewData裡的Htm系統會自動把標籤轉換而達不到預覽的效果, 我們如果要呈現解析後的HTML則要調用@MvcHtmlString.C ...
- 00 LabVIEW中类的动态类型处理
1.父类使用自己的Method,连线默认为父类自己的控件 2.如果子类没有重写父类的Method,则子类使用父类方法时,直接创建出来即自己的数据类型 3.如果子类重写了父类的Method,则子类使 ...
- Python os 标准库使用
os模块是python自带的一个核心模块,用于和操作系统对象进行交互. 1.导入模块获取帮助 >>> import os>>> help(os)>>&g ...
- Unity3d使用UGUI实现长按功能
UGUI的Button组件只有OnClick事件的监听,要实现长按功能,要监听按下事件和抬起事件,所以要使用到EventTrigger组件中的OnPointerDown和OnPointerUp来监听. ...
- Unity3D优化总结(一)
1.如使用碰撞器,简单的模型尽量使用自带的碰撞器如BoxCollider,少使用Mesh Collider. 2.如要使用Mesh Collider,可以做一个专用的模型(尽量少网格)做为Mesh C ...
- java 启动 shell脚本
run.sh p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px "PingFang SC"; color: #000000 ...
- openstack-lanch an instance and nova compute log analysis
1. how to launch an instance: [root@localhost ~(keystone_admin)]# nova flavor-list+----+-----------+ ...