当前位置: 首页 > 编程日记 > 正文

C++11中std::tuple的使用

std::tuple是类似pair的模板。每个pair的成员类型都不相同,但每个pair都恰好有两个成员。不同std::tuple类型的成员类型也不相同,但一个std::tuple可以有任意数量的成员。每个确定的std::tuple类型的成员数目是固定的,但一个std::tuple类型的成员数目可以与另一个std::tuple类型不同。

但我们希望将一些数据组合成单一对象,但又不想麻烦地定义一个新数据结构来表示这些数据时,std::tuple是非常有用的。我们可以将std::tuple看作一个”快速而随意”的数据结构。

当我们定义一个std::tuple时,需要指出每个成员的类型。当我们创建一个std::tuple对象时,可以使用tuple的默认构造函数,它会对每个成员进行值初始化;也可以为每个成员提供一个初始值,此时的构造函数是explicit的,因此必须使用直接初始化方法。类似make_pair函数,标准库定义了make_tuple函数,我们还可以使用它来生成std::tuple对象。类似make_pair,make_tuple函数使用初始值的类型来推断tuple的类型。

一个std::tuple类型的成员数目是没有限制的,因此,tuple的成员都是未命名的。要访问一个tuple的成员,就要使用一个名为get的标准库函数模板。为了使用get,我们必须指定一个显式模板实参,它指出我们想要访问第几个成员。我们传递给get一个tuple对象,它返回指定成员的引用。get尖括号中的值必须是一个整型常量表达式。与往常一样,我们从0开始计数,意味着get<0>是第一个成员。

为了使用tuple_size或tuple_element,我们需要知道一个tuple对象的类型。与往常一样,确定一个对象的类型的最简单方法就是使用decltype。

std::tuple的关系和相等运算符的行为类似容器的对应操作。这些运算符逐对比较左侧tuple和右侧tuple的成员。只有两个tuple具有相同数量的成员时,我们才可以比较它们。而且,为了使用tuple的相等或不等运算符,对每对成员使用==运算符必须都是合法的;为了使用关系运算符,对每对成员使用<必须都是合法的。由于tuple定义了<和==运算符,我们可以将tuple序列传递给算法,并且可以在无序容器中将tuple作为关键字类型。

std::tuple的一个常见用途是从一个函数返回多个值。

std::tuple是一个模板,允许我们将多个不同类型的成员捆绑成单一对象。每个tuple包含指定数量的成员,但对一个给定的tuple类型,标准库并未限制我们可以定义的成员数量上限。

std::tuple中元素是被紧密地存储的(位于连续的内存区域),而不是链式结构。

std::tuple实现了多元组,这是一个编译期就确定大小的容器,可以容纳不同类型的元素。多元组类型在当前标准库中被定义为可以用任意数量参数初始化的类模板。每一模板参数确定多元组中一元素的类型。所以,多元组是一个多类型、大小固定的值的集合。

下面是从其他文章中copy的测试代码,详细内容介绍可以参考对应的reference:

#include "tuple.hpp"
#include <iostream>
#include <tuple>
#include <string>
#include <functional>
#include <utility>//
// reference: http://www.cplusplus.com/reference/tuple/tuple/
int test_tuple_4()
{
{ // tuple::tuple: Constructs a tuple object. This involves individually constructing its elements,// with an initialization that depends on the constructor form invokestd::tuple<int, char> first;                             // defaultstd::tuple<int, char> second(first);                    // copystd::tuple<int, char> third(std::make_tuple(20, 'b'));   // movestd::tuple<long, char> fourth(third);                   // implicit conversionstd::tuple<int, char> fifth(10, 'a');                    // initializationstd::tuple<int, char> sixth(std::make_pair(30, 'c'));    // from pair / movestd::cout << "sixth contains: " << std::get<0>(sixth);std::cout << " and " << std::get<1>(sixth) << '\n';
}{ // std::tuple::operator=: Each of the elements in the tuple object is assigned its corresponding elementstd::pair<int, char> mypair(0, ' ');std::tuple<int, char> a(10, 'x');std::tuple<long, char> b, c;b = a;                                // copy assignmentc = std::make_tuple(100L, 'Y');       // move assignmenta = c;                                // conversion assignmentc = std::make_tuple(100, 'z');        // conversion / move assignmenta = mypair;                           // from pair assignmenta = std::make_pair(2, 'b');           // form pair /move assignmentstd::cout << "c contains: " << std::get<0>(c);std::cout << " and " << std::get<1>(c) << '\n';
}{ // std::tuple::swap: Exchanges the content of the tuple object by the content of tpl,// which is another tuple of the same type (containing objects of the same types in the same order)std::tuple<int, char> a(10, 'x');std::tuple<int, char> b(20, 'y');a.swap(b);std::cout << "a contains: " << std::get<0>(a);std::cout << " and " << std::get<1>(a) << '\n';std::swap(a, b);std::cout << "a contains: " << std::get<0>(a);std::cout << " and " << std::get<1>(a) << '\n';
}{ // std::relational operators: Performs the appropriate comparison operation between the tuple objects lhs and rhsstd::tuple<int, char> a(10, 'x');std::tuple<char, char> b(10, 'x');std::tuple<char, char> c(10, 'y');if (a == b) std::cout << "a and b are equal\n";if (b != c) std::cout << "b and c are not equal\n";if (b<c) std::cout << "b is less than c\n";if (c>a) std::cout << "c is greater than a\n";if (a <= c) std::cout << "a is less than or equal to c\n";if (c >= b) std::cout << "c is greater than or equal to b\n";
}return 0;
}// reference: https://msdn.microsoft.com/en-us/library/bb982771.aspx
int test_tuple_3()
{typedef std::tuple<int, double, int, double> Mytuple;Mytuple c0(0, 1, 2, 3);// display contents " 0 1 2 3" std::cout << " " << std::get<0>(c0);std::cout << " " << std::get<1>(c0);std::cout << " " << std::get<2>(c0);std::cout << " " << std::get<3>(c0);std::cout << std::endl;Mytuple c1;c1 = c0;// display contents " 0 1 2 3" std::cout << " " << std::get<0>(c1);std::cout << " " << std::get<1>(c1);std::cout << " " << std::get<2>(c1);std::cout << " " << std::get<3>(c1);std::cout << std::endl;std::tuple<char, int> c2(std::make_pair('x', 4));// display contents " x 4" std::cout << " " << std::get<0>(c2);std::cout << " " << std::get<1>(c2);std::cout << std::endl;Mytuple c3(c0);// display contents " 0 1 2 3" std::cout << " " << std::get<0>(c3);std::cout << " " << std::get<1>(c3);std::cout << " " << std::get<2>(c3);std::cout << " " << std::get<3>(c3);std::cout << std::endl;typedef std::tuple<int, float, int, float> Mytuple2;Mytuple c4(Mytuple2(4, 5, 6, 7));// display contents " 4 5 6 7" std::cout << " " << std::get<0>(c4);std::cout << " " << std::get<1>(c4);std::cout << " " << std::get<2>(c4);std::cout << " " << std::get<3>(c4);std::cout << std::endl;return (0);
}///
// reference: http://zh.cppreference.com/w/cpp/utility/tuple
static std::tuple<double, char, std::string> get_student(int id)
{if (id == 0) return std::make_tuple(3.8, 'A', "Lisa Simpson");if (id == 1) return std::make_tuple(2.9, 'C', "Milhouse Van Houten");if (id == 2) return std::make_tuple(1.7, 'D', "Ralph Wiggum");throw std::invalid_argument("id");
}int test_tuple_2()
{auto student0 = get_student(0);std::cout << "ID: 0, "<< "GPA: " << std::get<0>(student0) << ", "<< "grade: " << std::get<1>(student0) << ", "<< "name: " << std::get<2>(student0) << '\n';double gpa1;char grade1;std::string name1;std::tie(gpa1, grade1, name1) = get_student(1);std::cout << "ID: 1, "<< "GPA: " << gpa1 << ", "<< "grade: " << grade1 << ", "<< "name: " << name1 << '\n';return 0;
}///
// reference: http://www.cplusplus.com/reference/tuple/
static void print_pack(std::tuple<std::string&&, int&&> pack)
{std::cout << std::get<0>(pack) << ", " << std::get<1>(pack) << '\n';
}static void fun(int &a)
{a = 15;
}int test_tuple_1()
{
{ // std::tuple_element: class template, Class designed to access the type of the Ith element in a tuple.// It is a simple class with a single member type, tuple_element::type,// defined as an alias of the type of the Ith element in a tuple of type T.auto mytuple = std::make_tuple(10, 'a');std::tuple_element<0, decltype(mytuple)>::type first = std::get<0>(mytuple);std::tuple_element<1, decltype(mytuple)>::type second = std::get<1>(mytuple);std::cout << "mytuple contains: " << first << " and " << second << '\n';
}{ // std::tuple_size: Class template designed to access the number of elements in a tuplestd::tuple<int, char, double> mytuple(10, 'a', 3.14);std::cout << "mytuple has ";std::cout << std::tuple_size<decltype(mytuple)>::value;std::cout << " elements." << '\n';
}{ // std::forward_as_tuple: function template, Constructs a tuple object with rvalue references// to the elements in args suitable to be forwarded as argument to a function.std::string str("John");print_pack(std::forward_as_tuple(str + " Smith", 25));print_pack(std::forward_as_tuple(str + " Daniels", 22));
}{ // std::get: funtion template, Returns a reference to the Ith element of tuple tpl.std::tuple<int, char> mytuple(10, 'a');std::get<0>(mytuple) = 20;std::cout << "mytuple contains: ";std::cout << std::get<0>(mytuple) << " and " << std::get<1>(mytuple);std::cout << std::endl;
}{ // std::make_tuple: function template, Constructs an object of the appropriate tuple type// to contain the elements specified in argsauto first = std::make_tuple(10, 'a');             // tuple < int, char >const int a = 0; int b[3];                         // decayed types:auto second = std::make_tuple(a, b);               // tuple < int, int* >auto third = std::make_tuple(std::ref(a), "abc");  // tuple < const int&, const char* >std::cout << "third contains: " << std::get<0>(third);std::cout << " and " << std::get<1>(third);std::cout << std::endl;
}{ // std::tie: function template, Constructs a tuple object whose elements are references// to the arguments in args, in the same order// std::ignore: object, This object ignores any value assigned to it. It is designed to be used as an// argument for tie to indicate that a specific element in a tuple should be ignored.int myint;char mychar;std::tuple<int, float, char> mytuple;mytuple = std::make_tuple(10, 2.6, 'a');          // packing values into tuplestd::tie(myint, std::ignore, mychar) = mytuple;   // unpacking tuple into variablesstd::cout << "myint contains: " << myint << '\n';std::cout << "mychar contains: " << mychar << '\n';
}{ // std::tuple_cat: function template, Constructs an object of the appropriate tuple type// to contain a concatenation of the elements of all the tuples in tpls, in the same orderstd::tuple<float, std::string> mytuple(3.14, "pi");std::pair<int, char> mypair(10, 'a');auto myauto = std::tuple_cat(mytuple, std::tuple<int, char>(mypair));std::cout << "myauto contains: " << '\n';std::cout << std::get<0>(myauto) << '\n';std::cout << std::get<1>(myauto) << '\n';std::cout << std::get<2>(myauto) << '\n';std::cout << std::get<3>(myauto) << '\n';
}{ // tuple::tuple: A tuple is an object capable to hold a collection of elements.// Each element can be of a different type.std::tuple<int, char> foo(10, 'x');auto bar = std::make_tuple("test", 3.1, 14, 'y');std::get<2>(bar) = 100;                                    // access elementint myint; char mychar;std::tie(myint, mychar) = foo;                            // unpack elementsstd::tie(std::ignore, std::ignore, myint, mychar) = bar;  // unpack (with ignore)mychar = std::get<3>(bar);std::get<0>(foo) = std::get<2>(bar);std::get<1>(foo) = mychar;std::cout << "foo contains: ";std::cout << std::get<0>(foo) << ' ';std::cout << std::get<1>(foo) << '\n';
}{std::tuple<int, char> foo{ 12, 'a' };std::cout << std::get<0>(foo) << "\n"; // 12fun(std::get<0>(foo));std::cout << std::get<0>(foo) << "\n"; // 15
}return 0;
}

GitHub: https://github.com/fengbingchun/Messy_Test

相关文章:

PHP Countable接口

实现该接口可以使用count()方法来获取集合的总数转载于:https://www.cnblogs.com/xiaodo0/p/3611307.html

矩阵奇异值分解简介及C++/OpenCV/Eigen的三种实现

奇异值分解(singular value decomposition, SVD)&#xff1a;将矩阵分解为奇异向量(singular vector)和奇异值(singular value)。通过奇异值分解&#xff0c;我们会得到一些与特征分解相同类型的信息。然而&#xff0c;奇异值分解有更广泛的应用。每个实数矩阵都有一个奇异值分…

经典!工业界深度推荐系统与CTR预估必读的论文汇总

&#xff08;图片付费下载自视觉中国&#xff09;来源 | 深度传送门&#xff08;ID: gh_5faae7b50fc5&#xff09;导读&#xff1a;本文是“深度推荐系统”专栏的第十一篇文章&#xff0c;这个系列将介绍在深度学习的强力驱动下&#xff0c;给推荐系统工业界所带来的最前沿的变…

docker上传自己的镜像

https://blog.csdn.net/boonya/article/details/74906927 需要注意的就是命名规范 docker push 注册用户名/镜像名 tag命令修改为规范的镜像&#xff1a; docker tag boonya/tomcat-allow-remote boonyadocker/tomcat-allow-remote转载于:https://www.cnblogs.com/MC-Curry/p/1…

多个class相同的input标签 获取当前值!方法!

2019独角兽企业重金招聘Python工程师标准>>> var a $(this).prev( ".你的class" ).val(); 转载于:https://my.oschina.net/u/1169079/blog/210082

C++11中std::forward_list单向链表的使用

std::forward_list是在C11中引入的单向链表或叫正向列表。forward_list具有插入、删除表项速度快、消耗内存空间少的特点&#xff0c;但只能向前遍历。与其它序列容器(array、vector、deque)相比&#xff0c;forward_list在容器内任意位置的成员的插入、提取(extracting)、移动…

即学即用的30段Python实用代码

&#xff08;图片付费下载自视觉中国&#xff09;原标题 | 30 Helpful Python Snippets That You Can Learn in 30 Seconds or Less作 者 | Fatos Morina翻 译 | Pita & AI开发者Python是目前最流行的语言之一&#xff0c;它在数据科学、机器学习、web开发、脚本编写、自…

如何配置IntelliJ IDEA发布JavaEE项目?

一、以war的形式运行项目 步骤1 新建或者导入项目后&#xff0c;选择File菜单-》Project Structure...&#xff0c;如下图&#xff1a; 步骤2 配置项目类型&#xff0c;名字可以自定义&#xff1a; 说明&#xff1a;这里的Artifact如果没有配置好的话&#xff0c;配置Tomcat时没…

网络分布式软件bonic清除

近期&#xff0c;有一款网格计算软件&#xff0c;在很多服务器上进行了部署&#xff0c;利用cpu进行运算。虽然未构成安全隐患&#xff0c;但是比较消耗资源&#xff0c;影响设备正常运行。今天对设备彻底检查&#xff0c;发现了一个分布式计算软件boinc&#xff0c;他是利用网…

C++/C++11中std::list双向链表的使用

std::list是双向链表&#xff0c;是一个允许在序列中任何一处位置以常量耗时插入或删除元素且可以双向迭代的顺序容器。std::list中的每个元素保存了定位前一个元素及后一个元素的信息&#xff0c;允许在任何一处位置以常量耗时进行插入或删除操作&#xff0c;但不能进行直接随…

React组件设计之边界划分原则

简述 结合SOLID中的单一职责原则来进行组件的设计 Do one thing and do it well javaScript作为一个弱类型并在函数式和面对对象的领域里疯狂试探语言。SOLID原则可能与其他语言例如&#xff08;java&#xff09;的表现可能是不同的。不过作为软件开发领域通用的原则&#xff0…

阿里AI labs发布两大天猫精灵新品,将与平头哥共同定制智能语音芯片

作者 | 夕颜出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;2019 年&#xff0c;去年刮起的一阵智能音箱热浪似乎稍微冷却下来&#xff0c;新产品不再像雨后春笋一样层出不穷&#xff0c;挺过市场洗礼的产品更是凤毛麟角&#xff0c;这些产品的性能、技术支持和体验基…

js 中文匹配正则

为什么80%的码农都做不了架构师&#xff1f;>>> /^[\u4e00-\u9fa5]{2,4}$/gi.test() 匹配中文正则 转载于:https://my.oschina.net/fedde/blog/211852

Caffe中对cifar10执行train操作

参考Caffe source中examples/cifar10目录下内容。cifar10是一个用于普通物体识别的数据集&#xff0c;cifar10被分为10类,分别为airplane、automobile、bird、cat、deer、dog、frog、horse、ship、truck&#xff0c;关于cifar10的详细介绍可以参考&#xff1a; http://blog.csd…

解决掉这些痛点和难点,让知识图谱不再是“噱头”

&#xff08;图片付费下载自视觉中国&#xff09;作者| 夕颜出品| AI科技大本营&#xff08;ID:rgznai100&#xff09;2012 年&#xff0c;谷歌正式提出知识图谱的概念&#xff0c;当时&#xff0c;研究人员的主要目的是用来优化搜索引擎技术。今年初&#xff0c;谷歌前员工&am…

mongodb使用常用语法,持续更新

设置快捷命令D:\mongodb4.0.8\bin>mongod --config "D:\mongodb4.0.8\mongo.conf" --auth --install --serviceName "MongoDB"mongodb配置文件#数据库路径dbpathD:\mongodb4.0.8\data\db#日志输出文件路径logpathD:\mongodb4.0.8\data\log\MongoDB.log#…

Android之NDK开发的简单实例

NDK全称为Native Development Kit&#xff0c;是本地开发工具集。在Android开发中&#xff0c;有时为了能更好的重用以前的C/C的代码&#xff0c;需要将这些代码编译成相应的so&#xff0c;然后通地JNI以供上层JAVA调用。当然&#xff0c;也有的是为了更高的保护性和安全性。下…

阿里披露AI完整布局,飞天AI平台首次亮相

作者 | 夕颜编辑 | 唐小引出品 | AI 科技大本营&#xff08;ID:rgznai100&#xff09;9 月 26 日上午&#xff0c;在云栖大会阿里云飞天智能主论坛上&#xff0c;年轻的阿里巴巴副总裁、阿里云智能计算平台事业部总经理、高级研究员贾扬清与其在 Facebook 的老同事—— Faceboo…

使用Caffe基于cifar10进行物体识别

在http://blog.csdn.net/fengbingchun/article/details/72953284中对cifar10进行train&#xff0c;这里通过train得到的model&#xff0c;对图像进行识别。cifar10数据集共包括10类&#xff0c;按照0到9的顺序依次为airplane(飞机)、automobile(轿车)、bird(鸟)、cat(猫)、deer…

SoJpt Boot 2.3-3.8 发布,Spring Boot 使用 Jfinal 特性极速开发

SoJpt Boot 2.3-3.8 发布了。SoJpt Boot 基于 JFinal 与 Spring Boot制作, 实现了 Spring Boot 与 Jfinal 的混合双打,使 Spring Boot 下的开发者能够体验 Jfinal 的极速开发特性。新版更新内容如下&#xff1a; SoJpt-Boot-2.3-3.8 changelog 1、加入事务注解,Tx(value"c…

PL/SQL程序设计 第七章 包的创建和应用

7.1 引言包是一组相关过程、函数、变量、常量和游标等PL/SQL程序设计元素的组合&#xff0c;它具有面向对象程序设计语言的特点&#xff0c;是对这些PL/SQL 程序设计元素的封装。包类似于C和JAVA语言中的类&#xff0c;其中变量相当于类中的成员变量&#xff0c;过程和函数相当…

C++11中头文件chrono的使用

在C11中&#xff0c;<chrono>是标准模板库中与时间有关的头文件。该头文件中所有函数与类模板均定义在std::chrono命名空间中。 std::chrono是在C11中引入的&#xff0c;是一个模板库&#xff0c;用来处理时间和日期的Time library。要使用chrono库&#xff0c;需要incl…

为什么平头哥做芯片如此迅猛?

作者 | 胡巍巍 发自杭州云栖大会责编 | 唐小引来源 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;2018年10月31日&#xff0c;阿里旗下的平头哥半导体有限公司成立。如今&#xff0c;平头哥成立不到一年&#xff0c;就已成绩斐然。2019年9月25日&#xff0c;阿里巴巴旗…

Vue 组件库 heyui@1.18.0 发布,新增地址选择、图片预览组件

开发四年只会写业务代码&#xff0c;分布式高并发都不会还做程序员&#xff1f; 新增 CategoryPicker 新增组件 CategoryPicker&#xff0c;地址级联组件的最佳方案。 <CategoryPicker :option"option" v-model"value"/> 相关文档 ImagePreview 新…

HTML5 Dashboard – 那些让你激动的 Web 技术

HTML5 Dashboard 是一个 Mozilla 推出的项目&#xff0c;里面展示了最前沿的 HTML5&#xff0c;CSS3&#xff0c;JavaScript 技术。每一项技术都有简洁&#xff0c;在线演示以及详细的文档链接。这些技术将成为未来一段时间 Web 开发的顶尖技术&#xff0c;如果不想落伍的话就赶…

计算机解决问题没有奇技淫巧,但动态规划还是有点套路

作者 | labuladong来源 | labuladong&#xff08;ID:labuladong&#xff09; 【导读】动态规划算法似乎是一种很高深莫测的算法&#xff0c;你会在一些面试或算法书籍的高级技巧部分看到相关内容&#xff0c;什么状态转移方程&#xff0c;重叠子问题&#xff0c;最优子结构等高…

idea下,Jetty采用main方法启动web项目

为什么80%的码农都做不了架构师&#xff1f;>>> 对于maven多模块的spring web项目&#xff0c;本地开发时&#xff0c;启动的方式一般有如下几种&#xff1a; 使用容器&#xff08;tomcat/jetty/resin等&#xff09;&#xff0c;该方式需要ide支持&#xff0c;而社…

概率论中均值、方差、标准差介绍及C++/OpenCV/Eigen的三种实现

概率论是用于表示不确定性声明(statement)的数学框架。它不仅提供了量化不确定性的方法&#xff0c;也提供了用于导出新的不确定性声明的公理。在人工智能领域&#xff0c;概率论主要有两种用途。首先&#xff0c;概率法则告诉我们AI系统如何推理&#xff0c;据此我们设计一些算…

[转]CentOS 5.5下FTP安装及配置

一、FTP的安装 1、检测是否安装了FTP : [rootlocalhost ~]# rpm -q vsftpd vsftpd-2.0.5-16.el5_5.1 否则显示:[rootlocalhost ~]# package vsftpd is not installed 查看ftp运行状态 service vsftpd status 2、如果没安装FTP&#xff0c;运行yum install vsftpd命令进行安装 如…

C++11中头文件thread的使用

C11中加入了<thread>头文件&#xff0c;此头文件主要声明了std::thread线程类。C11的标准类std::thread对线程进行了封装。std::thread代表了一个线程对象。应用C11中的std::thread便于多线程程序的移值。 <thread>是C标准程序库中的一个头文件&#xff0c;定义了…