美文网首页
C++11 模板元编程 - TypeList应用举例

C++11 模板元编程 - TypeList应用举例

作者: MagicBowen | 来源:发表于2016-09-16 11:09 被阅读432次

使用TypeList可以一次对一组类型进行操纵,关于如何应用它是一个非常有想象力的事情。例如我们可以用TypeList轻易地实现一个trait工具,用于判断某一类型是否是C++内置类型:

// "tlp/traits/IsBuiltIn.h"

template<typename T>
struct IsBuiltIn
{
private:
    using BuiltInTypes = __type_list(char, wchar_t, char16_t, char32_t, bool, short, int, long, long long, float, double, long double);

public:
    using Result = __is_included(BuiltInTypes, T);
};

#define __is_built_in(...)  typename IsBuiltIn<__VA_ARGS__>::Result
TEST("estimate a type whether a built in type")
{
    struct Object {};

    ASSERT_TRUE(__is_built_in(char));
    ASSERT_FALSE(__is_built_in(Object));
};

下面我们再介绍一种使用TypeList完成类型创建的设计技巧,这种设计技巧可以被用于C++自动代码生成,威力非常强大。

TLP中list的算法里有一个__scatter_inherits(),它让用户传入一个TypeList,以及一个模板template<typename> class Unit__scatter_inherits()可以生成一个目标类,这个目标类继承自每个TypeList的元素应用Unit后的类型。下面是一个例子:

template<typename T> struct Holder { T field; };

using Aggregator = __scatter_inherits(__type_list(int, short, char), Holder);

如上我们通过__scatter_inherits()创建了类型Aggregator,它多重继承自Holder<int>Holder<short>Holder<char>(见下面图示)。

最终Aggregator相当于有三个类型分别是int、short和char的成员变量。可以这样调用它的成员变量:

Aggregator object;

object.Holder<int>::field = 5;
object.Holder<char>::field = 'a';

__scatter_inherits()的实现如下:

// "tlp/list/algo/ScatterInherits.h"

template<typename TL, template<typename> class Unit> struct ScatterInherits;

template<template<typename> class Unit>
struct ScatterInherits<NullType, Unit>
{
};

template<typename Atom, template<typename> class Unit>
struct ScatterInherits : Unit<Atom>
{
};

template<typename Head, typename Tail, template<typename> class Unit>
struct ScatterInherits<TypeElem<Head, Tail>, Unit>
: ScatterInherits<Head, Unit>
, ScatterInherits<Tail, Unit>
{
};

#define __scatter_inherits(...) ScatterInherits<__VA_ARGS__>

__scatter_inherits()的实现并不复杂,它采用多重继承的方式,递归地继承自Holder<T>

有时我们想控制让这种继承关系能够保持单一继承。于是TLP同时提供了__linear_inherits(),它的参数和__scatter_inherits()相同,差别是__linear_inherits()创建的类型的继承关系是一条单向继承链。

下面的代码示例中,我们创建了类型Aggregator,它包含一组重载的成员方法void visit(const T& t)

template<typename T, typename Base>
struct Holder : Base
{
    void visit(const T& t)
    {
        std::cout << t << std::endl;
    };
};

using Aggregator = __linear_inherits(__type_list(int, short, char), Holder);

Aggregator object;
object.visit('a');
object.visit(-5);

上面代码示例中使用了__linear_inherits(),所以Aggregator的继承关系图是线性的。关于__linear_inherits()的具体实现请参考“tlp/list/algo/LinearInherits.h”。

这两个工具:__scatter_inherits()__linear_inherits()都允许客户通过一个TypeList和一个Unit模板来做类型生成,差别仅在于目标类型的继承方式不同。它们的强大之处在于它们通过组合的手段来生成目标类型,而把组合元素以一个数据结构和算法的方式交给了客户。


Traits in TLP

返回 C++11模板元编程 - 目录

相关文章

  • C++11 模板元编程 - TypeList应用举例

    使用TypeList可以一次对一组类型进行操纵,关于如何应用它是一个非常有想象力的事情。例如我们可以用TypeLi...

  • C++11 模板元编程 - TypeList

    对函数式编程来说,list是其中最基础也是最重要的数据结构。通过list可以轻易地构造出tree,map等复杂数据...

  • C++11 模板元编程 - TypeList高阶算法

    针对list的高阶算法,是允许用户在使用时传入别的元函数做参数的元函数。在函数式语言里对于list的高阶元函数(如...

  • C++11 模板元编程 - TypeList基本算法

    有了list的结构定义,我们就可以为其定义相关算法了。由于list是递归结构,所以其算法也都是递归算法。 一般情况...

  • C++11 模板元编程 - TypeList数据结构

    在函数式语言中list基本都是递归式结构,类似:{elem, {elem, {elem, ...}}}。 可以看到...

  • C++11 模板元编程 - 模板元编程的应用

    本节开始我们通过使用C++模板元编程去解决一些实际问题,来展示模板元编程针对现实问题的使用方法和设计技巧。本节中的...

  • 21 Typelist

    Typelist解析 Typelist是类型元编程的核心数据结构,不同于大多数运行期数据结构,typelist不允...

  • C++11 模板元编程 - 元编程

    从本节开始我们将模板元编程当做一门独立的函数式语言来讨论它的方方面面。 所谓元编程,就是指可以产生程序的程序。由于...

  • C++11 模板元编程 - 模板递归

    模板可以被递归调用,在模板递归的过程中,可以执行前面我们提到的两种编译期计算:数值计算和类型计算。 下面我们用模板...

  • C++11 模板元编程 - 元函数

    我们继续演进前面那个无聊的类型计算的例子,来得出元函数的定义。 前面我们实现了PointerOf,它对于传进的任意...

网友评论

      本文标题:C++11 模板元编程 - TypeList应用举例

      本文链接:https://www.haomeiwen.com/subject/uyfiettx.html