zoukankan      html  css  js  c++  java
  • 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;
    }
    
    
  • 相关阅读:
    随笔2
    随笔
    关于updateElement接口
    随笔1
    本地访问正常,服务器访问乱码 记录
    Redis (error) NOAUTH Authentication required.解决方法
    tomcat启动很慢 停留在 At least one JAR was scanned for TLDs yet contained no TLDs.
    微信公众号消息回复
    微信公众号 报token验证失败
    idea中web.xml报错 Servlet should have a mapping
  • 原文地址:https://www.cnblogs.com/Gaaagaa/p/12130392.html
Copyright © 2011-2022 走看看