设为首页 加入收藏

TOP

C++11模版元编程(五)
2015-11-21 01:03:04 来源: 作者: 【 】 浏览:15
Tags:模版 编程
要根据当前的type_index来遍历Variant的所有类型,找到对应的类型然后调用该类型的析构函数。
?
?
void Destroy(const type_index& index, void * buf)
? ? {
? ? ? ? std::initializer_list{(Destroy0(index, buf), 0)...};
? ? }
?
? ? template
? ? void Destroy0(const type_index& id, void* data)
? ? {
? ? ? ? if (id == type_index(typeid(T)))
? ? ? ? ? ? reinterpret_cast(data)->~T();
? ? }
?
  这里,我们通过初始化列表和逗号表达式来展开可变模板参数,在展开的过程中查找对应的类型,如果找到了则析构。在Variant构造时还需要注意一个细节是,Variant不能接受没有预先定义的类型,所以在构造Variant时,需要限定类型必须在预定义的类型范围当中,这里通过type_traits的enable_if来限定模板参数的类型。
?
?
template
? ? class = typename std::enable_if::type, Types...>::value>::type> Variant(T&& value) : m_typeIndex(typeid(void)){
? ? ? ? ? ? Destroy(m_typeIndex, &m_data);
? ? ? ? ? ? typedef typename std::remove_reference::type U;
? ? ? ? ? ? new(&m_data) U(std::forward(value));
? ? ? ? ? ? m_typeIndex = type_index(typeid(U));
? ? }
?
  这里enbale_if的条件就是前面实现的元函数Contains的值,当没有在预定义的类型中找到对应的类型时,即Contains返回false时,编译期会报一个编译错误。
?
  最后还需要实现内置的Vistit功能,Visit的实现需要先通过定义一系列的访问函数,然后再遍历这些函数,遍历过程中,判断函数的第一个参数类型的type_index是否与当前的type_index相同,如果相同则获取当前类型的值。
?
?
template
? ? void Visit(F&& f){
? ? ? ? using T = typename Function_Traits::template arg<0>::type;
? ? ? ? if (Is())
? ? ? ? ? ? f(Get());
? ? }
?
? ? template
? ? void Visit(F&& f, Rest&&... rest){
? ? ? ? using T = typename Function_Traits::template arg<0>::type;
? ? ? ? if (Is())
? ? ? ? ? ? Visit(std::forward(f));
? ? ? ? else
? ? ? ? ? ? Visit(std::forward(rest)...);
? ? }
?
  Visit功能的实现利用了可变模板参数和function_traits,通过可变模板参数来遍历一系列的访问函数,遍历过程中,通过function_traits来获取第一个参数的类型,和Variant当前的type_index相同的则取值。为什么要获取访问函数第一个参数的类型呢?因为Variant的值是唯一的,只有一个值,所以获取的访问函数的第一个参数的类型就是Variant中存储的对象的实际类型。
?
7总结
?
  C++11中的一些特性比如type_traits、可变模板参数和tuple让模版元编程变得更简单也更强大,模版元编程虽然功能强大,但也比较复杂,要用好模版元,需要我们转变思维方式,在掌握基本的理论的基础上,再认真揣摩模版元的一些常用技巧,这些技巧是有规律可循的,基本上都是通过重定义、递归和偏特化等手法来实现的,当我们对这些基本技巧很熟悉的时候再结合不断地实践,相信对模版元编程就能做到“游刃有余”了。
?
?
首页 上一页 2 3 4 5 下一页 尾页 5/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇UVALive6814 Lexicography 下一篇UVA - 1616 Caravan Robbers 二分..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: