189 8069 5689

跟我学c++高级篇——模板元编程之一萃取和元函数-创新互联

一、模板元编程和萃取

前面已经在中级篇中对模板元编程进行了一个初步的分析说明,这里就不再重复这段内容。同样,萃取技术在前面也反复的的分析过。但做为模板应用的萃取是元编程的一个重要机制,c++的STL中提供的type_traits头文件中提供了大量的相关操作。在c++语言中,元数据可以分为两大类,即类型和非类型。随着c++版本的不断迭代,这两种类型的在模板中的应用的统一化已经非常明朗。
元编程的模板代码在编译期展开的过程中,经常需要处理一些参数的类型,而c++是缺少天然RTTI的类型获得的,这就要求在元编程中广泛的使用萃取技术。元编程在编译期的展开,意味着可以把运行时的时间转移到编译期,还可以通过模板展开静态多态的应用。
但c++早期对模板元编程支持的不足,导致模板元编程基本停留在一些特定的人员和场合的应用,开发多年c++的程序员不知道元编程这个概念都不是小概率事件。但模板元编程的代码可以做到直观可见,编译时和编写时保持一致的不变性,这就使得其应用的前景还是非常不错的。

成都创新互联专注于企业全网整合营销推广、网站重做改版、沁阳网站定制设计、自适应品牌网站建设、HTML5建站商城网站开发、集团公司官网建设、外贸营销网站建设、高端网站制作、响应式网页设计等建站业务,价格优惠性价比高,为沁阳等各大城市提供网站开发制作服务。二、元函数

所谓元函数,其实就是“一个操作元数据并可以在编译期调用的函数”,它一般有下面的特点:它是一个所有参数都是类型的类模板或者其有一个“type”的可访问的嵌套结果类型的类。看到这个是不是想起了c++17中的xxxx_t,或者更早一些的直接访问的::type。
元函数一般分为普通的元函数,数值型元函数和无参元函数。元函数操作的是元数据,那么什么是元数据呢?既然元数据是在编译期运行的,那么其在编译期使用的数值即为元数据。元数据主要包括以下三类:
1、类型参数
2、非类型参数如数字类型和枚举类型
3、STL模板如std::vector等
这些内容不是一成不变的,随着c++标准的不断迭代,可能一些原来不能称之为元数据的数据成为了元数据,这个要根据标准来划定。

三、元编程

下面写一个最简单的元函数:

templatestruct typeDef
{
    using type = T;
};

templatestruct valueType : typeDef{
     //constexpr控制编译期
    static constexpr T value = v;
};


int  main()
{
    using tType = valueType;
    using fFalse = valueType;

    std::cout<< tType::value<< std::endl;
    std::cout<< fFalse::value<< std::endl;
    std::cout<<"first type:"<< typeid(tType).name()<<"second type:"<< typeid(fFalse).name()<< std::endl;
}

这个你看是不是类似于STL中的一些模板类,std::integral_constant,通过这个模板可以推导出“template using bool_constant = integral_constant;”,进一步推导出“true_type”和“false_type”.下面看一个复杂一些的应用:

//前向声明
templatestruct add_const_ref_impl;

//实现类
templatestruct add_const_ref
{
    using type = typename add_const_ref_impl::value, T>::type;
};

//非引用增加引用和const,const&
templatestruct add_const_ref_impl{
    using type = typename std::add_lvalue_reference::type>::type;
};
//引用则去除引用返回类型
templatestruct add_const_ref_impl{
    using type = typename std::remove_reference::type;
};

void TestAddCR()
{
    using A = int&;
    using B = int;
    using C = int const&;

    std::cout<< std::is_same::value<< std::endl;
    std::cout<< std::is_same::value<< std::endl;
}
int  main()
{
    TestAddCR();
    return 0;
}

这个是《c++模板元编程》的一个习题,即实现一元元函数add_const_ref,如果T为一个引用类型,则返回T,否则返回T 的const&。那个书比较老,提示还用boost::is_same来测试结果,这里都改成用STL标准库里的了。
一个函数在编写后,在实际应用的平台不同往往会产生输入的参数一致,但结果却有所不同的结果,这种现象被称为函数的副作用,而这类函数则被称为有副作用的函数。这种现象一般是因为一些环境变量或者硬件的些微不同造成的。而元函数由于是在编译期进行展开执行的,所以不会出现这种情况,所以元函数是一种没有副作用的函数。

四、总结

写到元编程,其实还是很矛盾的,毕竟元编程不是好相与的。但解决问题的手段可以很多,但目标还是不能动摇,该总结分析一下,还是要动手亲自走一次。元编程可以说是模板编程里最难理解和在一般应用中极少用的一门技术,与其在分析各种底层库时费脑筋,不如把它从基础上一点点攻克,这样再阅读一些开源的代码时就会很舒畅。有目标就好,就怕没有了目标!
为什么说矛盾呢?大牛们对元编程的态度并不一致,甚至可以说很分裂,就像光明和黑暗,一定会同时存在,只不过元编程会造成“语言的分裂”,或者说是使用元编程会形成极具个性化的风格的代码,使得代码难于维护和后续的扩展,这是不符合至少国内的一些人的目的。如果每个程序员成为了一个各自不同、不可替代的螺丝钉,对他们来说是一种灾难。
元编程系列全分解成很长的时间来完成,希望能坚持到最后。

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


网站栏目:跟我学c++高级篇——模板元编程之一萃取和元函数-创新互联
文章源于:http://cdxtjz.cn/article/cccspi.html

其他资讯