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/Gaaagaa/p/12130392.html

时间: 2024-11-06 21:42:04

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 参数列表解包

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

struct--二进制数据结构的打包与解包

介绍 struct模块包括一些函数,这些函数可以完成字节串与原生Python数据类型(如数字和字符串)之间的转换 函数与Struct类 struct提供了一组处理结构值的模块级函数,另外还有一个Struct类,这与处理正则表达式的compile类似. 类比正则:re.match(pattern, text) 使用这种模块级别的函数时,会先将pattern进行编译转换,这个转换是耗费资源的.因此可以先对pattern进行一个编译,comp = re.compile(pattern),comp.ma

Python中的参数解包:`*`表达式和 `**`表达式

目录 1.参数解包:方法调用中的*表达式和**表达式 2.参数解包:方法定义中的*表达式和**表达式 3.在元组,列表,集合和字典中解包 4.Extended Unpacking:赋值表达式左边的*表达式 1.参数解包:方法调用中的*表达式和**表达式 如果语法*表达式出现在函数调用中,则该表达式必须是可迭代的. 这些可迭代集合的元素被视为附加的位置参数. 对于调用f(x1, x2, *y, x3, x4),如果y等于序列[y1,...,yM],则等效于调用f(x1, x2, y1, ...,

tuple解包给类的构造函数

首先我们的第一步当然是将tuple解包.tuple提供了一个get函数来获取第N个元素.例如: get<1>(make_tuple(...)); 要将一个tuple全部拆解,就可以使用通过多次调用这个函数来进行解析,例如: auto tup = make_tuple(..........); func( get<0>(tup),get<1>(tup),get<2>(tup)......get<n>(tup) ); 而实际上,0,1,...n这个数

C++11中的Tuple和可变参数模版

C++11中的tuple是一个n元的可变元组,它相当于有n个元素的结构体,只不过这个结构体的成员都是匿名的,tuple中提供了一个get()方法来获取某个下标对应的元素的值.另外可以通过make_tuple()方法来构造一个tuple对象.具体用法如下 我们知道tuple中的元素个数是不确定的,而每个元素的类型通过模板参数指定,那么tuple是如何做到这些的呢?答案就是使用可变参数模板.在C++中,我们使用过printf函数,它的参数就是可变的,在C++11中也允许模板的参数也是可变的.举个例子

函数参数自动解包

你使用*, **可以自动的对一个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

python之参数解包

# 参数解包:将整个list当做参数传给函数 list = [1, 2, 4] def add_fn(a, b, c): return a + b + c sum = add_fn(*list) print("参数解包:", sum) 运行结果: 参数解包: 7

Lua学习教程之 可变参数数据打包与解包

利用table的pack与unpack进行数据打包与解包,测试代码如下: print("Test table.pack()----------------"); function printTable ( t ) if type(t) == "table" then for k,v in pairs(t) do printTable(v); end else print(t); end end local packData =function( ... ) loca