在用C++编写coroutine基础类的时候,需要参数的传递。
而基础类对参数类型一无所知,毕竟参数是与应用相关的。
此时,boost::any就派上用场了。
编写此类的时候并没有参考boost::any代码(因此功能肯定不如boost::any完善严谨),写完后做了一下参考,将命名向boost看齐
1. 先思考一下Any的用法:
Any obj;
obj = 5;
cout << any_cast<int>(obj) << endl;
obj = string("hello");
cout << any_cast<string>(obj) << endl;
int* p = new int(5);
obj = p;
cout << *any_cast<int*>(obj) << endl;
如上所示,obj可以被赋予“任何”类型的值:int,string,int*;
用户必须清楚any的底层类型,以在使用时候做cast转换(毕竟C++是强类型语言)。
不难推断出any实现使用了模板operator=;(还有模板构造函数,同理)
具有以下签名函数
template <typename T>
Any& operator=(const Any& rhs);
且Any本身是一个普通类,不能是模板类 (由Any obj;声明推断)
这里引来了一个问题:
既然any不是模板类,如何保存任意的数据类型?
毕竟常规都是这么做的:
template <typename T>
class Any
{
T value;
};
有个办法可以解决:让模板类继承自普通类:
class DummyHolder
{
public:
virtual ~DummyHolder() { }
virtual DummHolder* Copy() const = 0;
};
template <typename T>
class Holder : public DummyHolder
{
....
T value;
};
这样,在any类中添加一个唯一成员:
DummyHolder* pHolder;
any类的模板构造函数如下:
template <typename T>
Any(const T& value) :
pHolder(new Holder<T>(value))
{
}
这样的话,形如 Any obj(5);声明就合法了。
水到渠成,operator=实现如下:
Any& operator= (const Any& that)
{
if(this == &that)
return *this;
delete pHolder;
pHolder = (that.pHolder ? that.pHolder ->Copy() : 0);
return *this;
}
至此,基础any类完成了,下面还需要使用它,转为我们需要的类型,实现很简单,不说了。
唯一注意的是,需要将引用类型的引用“剥去”;
boost的实现很复杂,很全面。
我随手写了几行基本能用:
template <typename T>
struct remove_ref
{
typedef T noref_type;
};
template <typename T>
struct remove_ref<T& >
{
typedef T noref_type;
};
只需要对参数T做“剥去”动作即可:
typedef typename remove_ref<T>::noref_type noref_t;
PS:写模板的时候经常遇到一些匹配错误,特别是遇到一族偏特化的模板。
调试代码中加入typeid(T).name()会有一些帮助。