C++11 —— tuple 参数列表解包

??tuple 的主要用途,就是把各种类型的参数组合成一个新的数据关联体(结构体),相当于早期的 std::pair 的泛化版本。

??组合存储是方便了,但是,对于某些特定的应用场景,解包就成了个比较麻烦的事情。为此,我查看 gcc 8.2.0 版的 STL 源码,从 functional 文件中 提取出 tuple 索引号生成的代码,并略作更名(避免冲突),得到如下 nstuple 命名空间内的代码,这其中可变参数模板类的递归构建,用得甚是精妙,值得学习。

namespace nstuple
{

    template< size_t... _Indexes >
    struct X_Index_tuple
    {

    };

    /// Builds an X_Index_tuple< 0, 1, 2, ..., _Num - 1 >.
    template< std::size_t _Num, typename _Tuple = X_Index_tuple<> >
    struct X_Build_index_tuple;

    template< std::size_t _Num, size_t... _Indexes >
    struct X_Build_index_tuple<_Num, X_Index_tuple< _Indexes... > >
        : X_Build_index_tuple< _Num - 1, X_Index_tuple< _Indexes..., sizeof...(_Indexes) > >
    {

    };

    template< size_t... _Indexes >
    struct X_Build_index_tuple< 0, X_Index_tuple< _Indexes... > >
    {
        typedef X_Index_tuple< _Indexes... > __type;
    };

}; // namespace nstuple

??有了 nstuple 中的代码,我们就可以利用 std::get() 操作,轻松的解包 tuple 的各个参数了,实现的示例代码如下所示:

#include <iostream>
#include <tuple>
#include <utility>

namespace nstuple
{
    // 此处省略 nstuple 的代码,与上面提到的 nstuple 命名空间内的源码一致
    // ......
}; // namespace nstuple

void test_func(int v1, int v2, float v3)
{
    std::cout << "(v1, v2, v3) == "
              << "("  << v1
              << ", " << v2
              << ", " << v3
              << ")"  << std::endl;
}

using X_Tuple   = std::tuple< int, int, float >;
using X_Indices = nstuple::X_Build_index_tuple< std::tuple_size< X_Tuple >::value >::__type;

template< size_t... _Ind >
void _S_Invoke(X_Tuple && xtuple, nstuple::X_Index_tuple< _Ind... >)
{
    // 解包 xtuple 参数,传递给 test_func() 函数调用
    test_func(std::get< _Ind >(std::move(xtuple))...);
}

int main(int argc, char * argv[])
{
    X_Tuple xtuple{ 100, 200, 3.141593F };
    _S_Invoke(std::forward< X_Tuple >(xtuple), X_Indices());

    return 0;
}

原文地址:https://www.cnblogs.com/VxGaaagaa/p/10124281.html

时间: 2024-11-01 14:01:14

C++11 —— tuple 参数列表解包的相关文章

C++11 —— 获取 tuple 参数列表中指定数据类型的索引位置

1. 问题背景 ??在 C++11 的标准中,我们可以通过 std::get< Index >(tuple) (以常量整数值为索引号)操作 tuple 中的参数,而到了 C++14 之后的标准,新增了 std::get< Type >(tuple) (以数据类型为索引)的方式操作 tuple 中的参数.那么,若只是在 C++11 标准中,是否有办法使用 以数据类型为索引 的方式操作 tuple 中的参数呢? 2. 解决办法 ??解决上面所提到的问题,其本质上,就是要解决 如何获取

C++11 tuple元组

C++11 tuple 元组 tuple容器(元组), 是表示元组容器, 是不包含任何结构的,快速而低质(粗制滥造, quick and dirty)的, 可以用于函数返回多个返回值; tuple容器, 可以使用直接初始化, 和"make_tuple()"初始化, 访问元素使用"get<>()"方法, 注意get里面的位置信息, 必须是常量表达式(const expression); 可以通过"std::tuple_size<declty

C++ 11可变参数接口设计在模板编程中应用的一点点总结

概述 本人对模板编程的应用并非很深,若要用一句话总结我个人对模板编程的理解,我想说的是:模板编程是对类定义的弱化. 如何理解“类定义的弱化”? 一个完整的类有如下几部分组成: 类的名称: 类的成员变量(或属性,C#中属性和成员变量还是有区别的): 类的成员方法: 从编译器的角度看,我们必须明确指定以上3部分,才算完整地定义了一个类并且编译通过. 所谓的“类弱化”,是指类的设计者在定义类的时候,并没有完整定义一个类,而是把类的其中一部分的定义留给类的使用者. 从传统才c++98看,通过模板类,使用

python 学习笔记 11 -- 使用参数使你的程序变得更性感

当然,在之前的系列中,我已介绍如何给 Python 脚本传参,当然,今天不会继续介绍这么无聊的东东.首先使用 python 的sys.argv 传参的话,就固定了参数的个数.顺序以及格式,这么死的规定如何性感? I have a dream , to make my code much sexer ! 今天我们简单介绍一下如何更加随性的给 python 脚本传参.效果如下: [email protected]:/tmp$ python arg.py -h NAME: project with u

定义可变参数和定义一个list或tuple参数相比,仅仅在参数前面加了一个*号

定义可变参数和定义一个list或tuple参数相比,仅仅在参数前面加了一个*号.在函数内部,参数numbers接收到的是一个tuple,因此,函数代码完全不变.但是,调用该函数时,可以传入任意个参数,包括0个参数: def calc(*numbers): sum = 0 for n in numbers: sum = sum + n * n return sum >>> calc(1, 2, 3) 14 >>> calc(1, 3, 5, 7) 84 def calc(

C++11 —— 解包 tuple 参数列表

??tuple 的主要用途,就是把各种类型的参数组合成一个新的数据关联体(结构体),相当于早期的 std::pair 的泛化版本. ??组合存储是方便了,但是,对于某些特定的应用场景,解包就成了个比较麻烦的事情.为此,我查看 gcc 8.2.0 版的 STL 源码,从 functional 文件中 提取出 tuple 索引号生成的代码,并略作更名(避免冲突),得到如下 nstuple 命名空间内的代码,这其中可变参数模板类的递归构建,用得甚是精妙,值得学习. namespace nstuple

C++11 可变参数模板

在C++11之前, 有两个典型的受制于模板功能不强而导致代码重复难看的问题, 那就 function object 和 tuple. 拿 function objects 来说, 需要一个返回类型参数及N个参数类型参数. 但因为变长参数模板不受支持,导致不得不重复书写7.8个模板类,但最终也只能支持7.8个参数的 function object.C++11中最终为我们带来了强大的变长 参数模板功能,这些问题也随之迎刃而解了. 可变参数模板(Variadic Template)故名思义,即可以接受

c++11——可变参数模板

在c++11之前,类模板和函数模板只能含有固定数量的模板参数,c++11增加了可变模板参数特性:允许模板定义中包含0到任意个模板参数.声明可变参数模板时,需要在typename或class后面加上省略号"...".     省略号的作用有两个: 1. 声明一个参数包,这个参数包中可以包含0到任意个模板参数 2. 在模板定义的右边,可以将参数包展开成一个一个独立的参数 1. 可变参数模板函数 可变参数模板函数的定义如下: template<class... T> void f

函数参数自动解包

你使用*, **可以自动的对一个list,dict做函数参数,自动的解包 例子: def draw_point(x, y): # do some magic point_foo = (3, 4) point_bar = {'y': 3, 'x': 2} draw_point(*point_foo) draw_point(**point_bar) 这是一个非常捷径的用法. NOTE: 请看这两个程序的不同... def cheeseshop(kind, *arguments, **keywords