范型编程-前言

前一段时间,因为工作上的需要,自己山寨了一套stl。

出于学习范型编程的目的,

出于优化c++流的性能,易用性,

出于优化stl内存模型的目的,

出于优化减少拷贝的目的,

出于兼容gcc 4.8+编译器,clang3.3+编译器的目的,

出于服务框架整体性,结合序列化,格式化,IO优化的目的,

出于增加如skiplist,btree ,matrix为基础的大数据容器,为大数据索引等提供工具。

一年前,曾经些过一些关于实现云平台的构想,这段时间主要是集中在业务层的工作居多,更加深了我之前对云服务框架的理解,宏观上的模型还是保持一致,不同在与,前面我的更多的侧重点是在存储刚面考虑多一些,这一年的工作,主要集中计算方面,在设计和实现上增加了计算方面的考虑。

接下来,我逐步的将我学习以及实现过程的心路分享给大家。

stl的入口实际上是对编译器的分解,需要对编译器支持的特性做特定的检查。

在开始之前还要补充几点限定。

这套stl的取名 wsl (walle standary lib)

支持gcc clang,I am sorry,不支持vc和其他编译器,在windows下不能运行(原谅我的自私)

运行环境 linux mac (iphone, android后续支持)

主要目的是在服务端,特别是多版本编译器(特别是大公司,那编译器版本的数量比美元都多)

gcc 支持4.8+

clang 支持3.3+

参考项目: LIBCXX3.3 googleperftool

注意:本系列并不范型的知识性文章,侧重在工程的应用,和优化算法的极少上,范型编程的知识,会提到一些知识点,读者可其他书籍,这里就不粘贴,拷贝了。

编译器的特性的检查,在另外一个专题介绍,这里线跳过这一步骤,直奔范型主题。

wsl入口文件,type_traits.h, stl的也是如此,在这个文件里,定义了大量的trait特性。有150之多,如 is_same, is_enum等等,他们的实现的方式也不近相同,从分类上来说,可以分为工具类,基础类,复杂类,转换类,pod类。

今天就从工具类型开始介绍一下范型编程

template

structintegral_constant{

staticconstT value = v;

typedefT value_type;

typedefintegral_constant type;

WA_CONSTEXPRoperatorvalue_type()constWA_NOEXCEPT {returnvalue; }

WA_CONSTEXPR value_typeoperator()()constWA_NOEXCEPT {returnvalue; }

};

template

constT integral_constant::value;

integral_constant是整个工具类的入口,是所有traits类的基类。

value_type 表示值的类型

value表示值

type 表示自己, 因此可以用::type::value来获取值

true_type和false_type两个特化类用来表示bool值类型的traits,很多traits类都需要继承它们。

typedefintegral_constant true_type;

typedefintegral_constant false_type;

在这里用到模版一个特化的方法,两个模版参数都进行特化,当然也有篇特化的使用,如下面的例子

#if defined(WA_COMPILER_NO_TEMPLATE_ALIASES)

template

structbool_constant:publicintegral_constant {};

#else

template

usingbool_constant = integral_constant;

#endif

这个例子中,将类型模版特化为bool型。这里会用到编译器的一个特性 “模版别名”,这个特性在c++11中才会有,实际上gcc4.8+, clang3.3都是完全支持c11的,为了防止在在部分android,iphone上的兼容线,预先做了一点向前兼容。

对模版别名稍作解释,在解释这个之前,先弄清楚“类型”, “模版”这个概念。

举个栗子,std::map 这个的std::map是模版类,也就是模版,int,std::string 是类型。

大家也都知道,c++中我们使用typedef 来给类型定义新的名称

如 typedef uint64_t user_id;这样在后后面定义函数时:

void foo(user_id);是可行的,同时定义 void foo(uint64_t);将不能通过编译,因为他们的本质类型都是uint64_t ,是错误的重载。

typedef 可以给类型重新定义名字,但是不能给模版重新定义名字。

如template typedef std::map my_map;这样将不能通过编译,因为 typedef不能给模版重命名。

这里就要用到c++11的关键字using,

template

using my_map = std::map;

今天就到这里,先认识一下范型编程和c++11的模版别名的特性。

下期主要内容:范型编程-模版编程与函数式编程

下期将通过type_traits的几个工具类 condition, type_or, type_not以及erlang的小例子,介绍一些范型编程与函数式编程的通用型,以及范型编程篇特化的一些用法。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180320G0FEE200?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券