C++模板 index_sequence使用示例详解

目录
  • 引言
  • integer_sequence
  • index_sequence
  • make_index_sequence
    • 使用场景
  • index_sequence_for
  • 结语

引言

integer_sequence 是 c++ 14中新增加的一个元编程工具

其衍生出来的还有如 index_sequencemake_index_sequenceindex_sequence_for等辅助工具

现在,让我们来浅尝一下这些东西吧!

integer_sequence

integer_sequence 其实没有什么特殊的,就是一个类

只不过他是index_sequence的基础

template<typename _Tp, _Tp... _Idx>
  struct integer_sequence
  {
    typedef _Tp value_type;
    static constexpr size_t size() noexcept { return sizeof...(_Idx); }
  };

index_sequence

index_sequence 会在编译期生成一个从0开始的序列

然后你就可以对其进行一些奇奇怪怪的操作

template <size_t... N> void print(std::index_sequence<N...>) {
  std::vector<int> res;
  (void)std::initializer_list<int>{
      ((res.push_back(N), std::cout << N << " "), 0)...};
  std::for_each(res.begin(), res.end(), [](int x) {std::cout << x << " ";});
}
int main() {
  auto t = std::make_index_sequence<10>();
  print(t);
  return 0;
}

比如 ((res.push_back(N), std::cout << N << " "), 0)...这句话,就会在编译期被展开

这里展开在了一个初始化列表中,小技巧

make_index_sequence

那么,index_sequence 是如何生成的呢?

有两种形式

  • 编译器内建
  • 递归式的生成

第二种方式嘛还是用到了元编程的惯用伎俩,特化,递归式的编程

template <int... N> struct index_seq {};
template <int N, int... M>
struct make_index_seq : public make_index_seq<N - 1, N - 1, M...> {};
template <int... M> struct make_index_seq<0, M...> : public index_seq<M...> {};

对齐使用也是一样的形式

template <int... N> void print(index_seq<N...>) {
  (void)std::initializer_list<int>{((std::cout << N << " "), 0)...};
}
int main() {
  auto r = make_index_seq<100>();
  print(r);
  return 0;
}

使用场景

刚才,看见了print去打印的时候打印了 0-(N-1)的元素

那么,这个行为是在编译期展开的,我们就可以用到其他需要常量的地方

比如一个简单的需求:

打印tuple

template <typename T, typename F, int...N>
void exec_for_tuple(const T& tup, F&& func, index_seq<N...>) {
  (void)std::initializer_list<int> {
      (func(std::get<N>(tup)), 0)...
  };
}
template <typename Func, typename ...Arg>
void for_tuple(Func&& func, std::tuple<Arg...> tuple) {
  exec_for_tuple(tuple, std::forward<Func>(func), make_index_seq<sizeof...(Arg)>());
}

exec_for_tuple部分应该非常好懂,但是为什么中间还要再转发一层呢?

因为tuple元素的个数我们不能直接获取到,我们写的又要是一个通用的函数

所以要通过 sizeof...(arg) 这种伎俩来将其元素个数计算出来

如何调用呢?

如下所示:

std::tuple<int, int, double> tuple{1, 2, 3.0};
for_tuple([](auto t) {
  std::cout << t << " ";
}, tuple);

index_sequence_for

那么,看到现在,你知道 index_sequence_for又是何物吗?

其实吧,刚才就已经见过 index_sequence_for这个东西了

其实就是计算可变长模板参数的个数,然后将其长度做成一个sequence出来

template<typename... _Types>
using index_sequence_for = make_index_seq<sizeof...(_Types)>;

结语

index_sequence 是一个不起眼的家伙,可能你平时都不会去了解它,但是这个东西的用途还是有很多的,你想想,编译器制造一串序列的能力,在tuple这种模板中,使用其是不是更加方便了,在bind这种模板中的参数上,若是使用它,是不是更加灵活好些了。

其实和tuple一个道理,在平常编程中,你也许不会使用它,但是在模板编程中,这是比较好的一个工具。

以上就是C++模板 index_sequence使用示例详解的详细内容,更多关于C++模板index_sequence的资料请关注我们其它相关文章!

(0)

相关推荐

  • C++超详细讲解模板的使用

    目录 一.函数模板 1.1函数模板概念 1.2 函数模板格式 1.3 函数模板的原理 1.4 函数模板的实例化 二.类模板 2.1 类模板的定义格式 2.2类模板的实例化 总结 一.函数模板 1.1函数模板概念 函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本. 1.2 函数模板格式 template<typename T1, typename T2,…,typename Tn> 返回值类型 函数名(参数列表){} template<

  • C++ 类模板与成员函数模板示例解析

    目录 类模板 类模板与成员函数模板的区别 类模板 前面以函数模板为例,介绍了具体化与实例化.那么对于类模板,有什么不同呢? 类包括成员变量和成员函数,他们都可以包含类模板的模板参数.而成员函数本身也可以是函数模板.看下面的两个类: // 类模板 template <typename T> class A { private: T t; public: void funcA(T t); }; template <typename T> void A<T>::funcA(T

  • C++函数模板的使用详解

    函数模板可以适用泛型来定义函数,其中泛型可以是(int, double, float)等替换.在函数重载过程中,通过将类型作为参数传递给模板,可使编译器自动产生该类型的函数. 工作原理:比如需要定义一个比大小的max函数,有三种类型的数据(int,double,float),可能就需要编写三个函数,这样既浪费时间,且容易出错.如: #include <iostream> using namespace std; int Max(int a, int b); double Max(double

  • 初识C++ Vector模板与实例化原理

    目录 引言 Vector 模板与实例化 性能 引言 之前学了字符串,字符,数字这些类型,字符串可以看出包含多个字符的序列,那么包含多个数字的序列该是啥,包含其他类型的呢,c++当中满足这个需求是vector,我们一起来看看吧. Vector 标准库类型vector表述对象的集合,可以看成一个存放其他对象的容器,但是这里要注意的是同一个vector集合当中智能容纳一个类型,容器里面的元素都有一一对应的索引,可以通过索引访问元素.当然,vector是标准库类型,使用需要使用加载,代码如下: #inc

  • C++将模板实现放入头文件原理解析

    目录 写在前面 例子 原因 分析 解决方案 方案一 方案二 参考 写在后面 写在前面 本文通过实例分析与讲解,解释了为什么C++一般将模板实现放在头文件中.这主要与C/C++的编译机制以及C++模板的实现原理相关,详情见正文.同时,本文给出了不将模板实现放在头文件中的解决方案. 例子 现有如下3个文件: // add.h template <typename T> T Add(const T &a, const T &b); // add.cpp #include "

  • C++模板以及实现vector实例详解

    目录 函数模板 类模板 Vector实现 简单的类模板实现代码及测试: win msvc编译器的实现: 容器的空间配置器 运算符重载与迭代器实现 最终vector的实现代码 总结 函数模板 函数模板:是不进行编译的,因为类型还不知道 模板的实例化:函数调用点进行实例化 模板函数:才是要被编译器所编译的 模板类型参数:typyname/class 模板非类型参数:模板非类型形参的详细阐述 模板的实参推演:可以根据用户传入的实参的类型,来推导出模板类型参数的具体 模板的特例化(专用化)的实例化 模板

  • GoJs 图片绘图模板Picture使用示例详解

    目录 前言 go.Picture的使用 go.Picture的属性 width.height.desiredSize属性 source属性 flip属性 imageStretch.imageAlignment属性 拓展 结语 前言 前面已经说过了通过go.TextBlock(文本)和go.Shape(集合图形)来丰富节点内部的显示内容.而有些时候需要在节点内部上传一些说明材料,恰好这些材料又是图片材料.如果拿图片和节点信息对照观看的话,一一对照会特别麻烦.如果能够在节点内部显示缩略图的话.在信息

  • GoJs连线绘图模板Link使用示例详解

    目录 前言 go.link的简单使用 go.Link的属性配置 routing属性 curve属性 corner.toEndSegmentLength.fromEndSegmentLength.fromShortLength.toShortLength属性 selectable.fromSpot.toSpot属性 总结 前言 可视化图形中除了携带很多信息的节点(node)之外,还需要知道他们之间的关系,而链接他们之间的连线在gojs中是使用go.link进行绘制.在渲染的时候我们根据数据的fro

  • php之Smarty模板使用方法示例详解

    本文详细剖析了smarty模板的使用方法,对于学习smarty的朋友有一定的参考价值.详情如下: 一.模板中的注释 每一个Smarty模板文件,都是通过Web前台语言(xhtml,css和javascript等)结合Smarty引擎的语法开发的. 用到的web前台开发的语言和原来的完全一样,注释也没有变化. Smarty注释语法是'左结束符变量值*'和'*右结束符变量值',在这两个定界符之间的内容都是注释内容,可以包含一行或多行,并且用户浏览网页查看原代码时不会看到注释,它只是模板内在的注释,以

  • AngularJs用户输入动态模板XSS攻击示例详解

    概述 XSS攻击是Web攻击中最常见的攻击方法之一,它是通过对网页注入可执行代码且成功地被浏览器执行,达到攻击的目的,形成了一次有效XSS攻击,一旦攻击成功,它可以获取用户的联系人列表,然后向联系人发送虚假诈骗信息,可以删除用户的日志等等,有时候还和其他攻击方式同时实施比如SQL注入攻击服务器和数据库.Click劫持.相对链接劫持等实施钓鱼,它带来的危害是巨大的,是web安全的头号大敌. 前情提要 angularJs通过"{{}}"来作为输出的标志,而对于双括号里面的内容angular

  • Go语言基础模板设计模式示例详解

    目录 概述 模板模式生活案例 策略模式涉及到两个角色 UML 总结 示例 概述 模板方法模式定义了一个算法的步骤,并允许子类别为一个或多个步骤提供其实践方式.让子类别在不改变算法架构的情况下,重新定义算法中的某些步骤 确定了步骤的执行顺序,单某些步骤因环境或人等因素具体实现是未知的 模板模式生活案例 请客吃饭[点菜->吃东西->结账],每个人点菜不一样,吃东西不一样,结账也不一样从某地到某地[起点->出行方式->终点]起点和终点不一一样,但是每个人出行方式是不一样的 Go没有封装.

  • GoJs图形绘图模板Shape示例详解

    目录 前言 Shape的使用 width和height属性 fill属性 stroke.strokeWidth.strokeDashArray属性 geometry属性 angle.scale属性 strokeCap strokeJoin属性 拓展 结语 前言 在可视化图形的展示过程中,节点内部往往不只是有文字描述,这样看起来很往往比较枯燥.在这个时候我们就可以在图形的节点内部加入一些几何图形.然后实现图形和文字的结合使用的话,不仅可以让节点内的内容更加形象,而且还可以通过图形标记对不同类型的节

  • GoJs分组绘图模板go.Group使用示例详解

    目录 前言 Group的使用 Group的属性 handlesDragDropForMembers.isSubGraphExpanded属性 isSubGraphExpanded属性 ungroupable.wasSubGraphExpanded属性 结语 前言 在可视化图形中,很多的节点和连线都有某一个特征或者属于某些分类,为了在使用可视化图形的时候更加直观的看出相同类型节点的集合,我们就会用到分组的绘图模板. Group的使用 //data nodes: [ { key: "1",

  • Vue中的vue-resource示例详解

    vue-resource特点 vue-resource插件具有以下特点: 1. 体积小 vue-resource非常小巧,在压缩以后只有大约12KB,服务端启用gzip压缩后只有4.5KB大小,这远比jQuery的体积要小得多. 2. 支持主流的浏览器 和Vue.js一样,vue-resource除了不支持IE 9以下的浏览器,其他主流的浏览器都支持. 3. 支持Promise API和URI Templates Promise是ES6的特性,Promise的中文含义为"先知",Pro

  • 对python 生成拼接xml报文的示例详解

    最近临时工作要生成xml报名,通过MQ接口发送.简单小程序. 自增长拼成xml报文 Test_001.py # encoding=utf-8 import time orderId = '' s1= "\n" # for ID in range(1,5): item1 = "<item>" + \ "<orderID>" + str(ID) + "</orderID>" + \ "

  • Django中的模型类设计及展示示例详解

    django中设计数据模型类是基于ORM的对象关系映射更方便的进行数据库中的数据操作. 对象关系映射 把面向对象中的类和数据库表--对应,通过操作类和对象,对数表实现数据操作,不需要写sql,由ORM框架生成 django实现了ORM框架,在项目中与数据库之间产生桥梁作用 django数据库定义模型的步骤如下: python manage.py makemigrations python mange.py migrate 在应用models.py中编写模型类,继承models.Model类 在模

随机推荐