您的位置:首页 > 教程 > C语言教程 > C++模板 index_sequence使用示例详解

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

2022-12-07 16:08:23 来源:易采站长站 作者:

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

目录引言integer_sequenceindex_sequencemake_index_sequence使用场景index_sequence_for结语引言integer_sequence是c+...

目录
引言
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开始的序javascript

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

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出tuWad

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

结语

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

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

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

如有侵权,请发邮件到 [email protected]

相关文章

  • VS2019项目打包生成.exe文件与Setup的步骤实现

    VS2019项目打包生成.exe文件与Setup的步骤实现

    对于Visual Studio Installer ,我们通常称为:setup项目,是一个用于自定义安装部署的项目方案。但是在VS2019中不见了,微软是有意废除安装项目的,合作了一个第三方的安装项目单独使用。
    2020-03-13
  • 基于c++ ege图形库实现五子棋游戏

    基于c++ ege图形库实现五子棋游戏

    本文分享的五子棋实例,制作基于ege图像库, 首先需要安装配置ege环境 就可以编写小游戏了. 用到的ege库函数不多 , 主要是基于c++的. 先看界面效果: 输入界面:(就是控制台) 游戏胜利界面
    2020-01-06
  • C++基于easyx图形库实现推箱子游戏

    C++基于easyx图形库实现推箱子游戏

    本文实例为大家分享了C++实现推箱子游戏的具体代码,供大家参考,具体内容如下 头文件: #includestdio.h#includestdlib.h//#includeWindows.h#includeconio.h#includegraphics.h#includestdbool.h //播放音乐需要
    2020-06-30
  • VS2019 Nuget找不到包的问题处理

    VS2019 Nuget找不到包的问题处理

    VS不记得改了什么设置之后,发现找不到EF 解决办法 1、点击右侧的设置按钮 2、弹出窗中左侧树形结构选择“程序包源”,再点击右上方的添加按钮 输入一下信息:https://www.nuget.org/a
    2020-03-27
  • visual studio2019的安装以及使用图文步骤详解

    visual studio2019的安装以及使用图文步骤详解

    一、下载安装包 下载地址 选择visual studio 2019的community版本 二、下载好后运行 三、组件的选择 如果是用来学CC++的话,选择以下两个就够了 之后如果还需要其他一些功能的话,可以后
    2020-03-08
  • VScode编译C++ 头文件显示not found的问题

    VScode编译C++ 头文件显示not found的问题

    一直用codeblocks,想试试vscode,结果这个问题给我弄懵逼了。一开始以为是iostream这个头文件not found,后来发现第一个头文件都会这样显示,放到后面就不会了,然而,光这一个显示not
    2020-03-20
  • C++多线程获取返回值方法详解

    C++多线程获取返回值方法详解

    在许多时候,我们会有这样的需求——即我们想要得到线程返回的值。但是在C++11 多线程中我们注意到,std::thread对象会忽略顶层函数的返回值。 那问题来了,我们要怎么获得线程的返
    2020-06-25
  • JVM系列之String.intern的性能解析

    JVM系列之String.intern的性能解析

    String对象有个特殊的StringTable字符串常量池,为了减少Heap中生成的字符串的数量,推荐尽量直接使用String Table中的字符串常量池中的元素。 那么String.intern的性能怎么样呢?我们一起来
    2020-06-23