[C++] std::tuple

这篇具有很好参考价值的文章主要介绍了[C++] std::tuple。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【C++】std::tuple

1、什么是tuple

​ std::tuple是C++11新标准引入的一个类模板,又称为元组,是一个固定大小的异构值集合,由std::pair泛化而来。pair可以看作是tuple的一种特殊情况,成员数目限定为两个。tuple可以有任意个成员数量,但是每个确定的tuple类型的成员数目是固定的。

​ 从概念上讲,它们类似于C的结构体,但是不具有命名的数据成员,我们也可以把他当做一个通用的结构体来用,不需要创建结构体又获取结构体的特征,在某些情况下可以取代结构体使程序更简洁,直观。

​ tuple 的应用场景很广泛,例如当需要存储多个不同类型的元素时,可以使用 tuple;当函数需要返回多个数据时,可以将这些数据存储在 tuple 中,函数只需返回一个 tuple 对象即可。

2、tuple的基本用法

①tuple对象的创建和初始化

tuple 本质上是一个以可变模板参数定义的类模板,它定义在 头文件并位于 std 命名空间中。因此要想使用 tuple 类模板,程序中需要首先引入以下代码:

#include <tuple>

实例化 tuple 模板类对象常用的方法有两种,一种是借助该类的构造函数,另一种是借助 make_tuple() 函数。

1)类的构造函数
constexpr tuple(); 				//无参构造函数
tuple( const Types&... args ); 	//拷贝构造函数
tuple (tuple&& tpl);			//移动构造函数

/*隐式类型转换构造函数*/
template< class... UTypes >
	tuple(const tuple<UTypes...>& other );	//左值方式
template< class... UTypes >
	tuple( tuple<UTypes...>&& other );		//右值方式

/*支持初始化列表的构造函数*/
explicit tuple (const Types&... elems);  	//左值方式
template <class... UTypes>
    explicit tuple (UTypes&&... elems);  	//右值方式

/*将pair对象转换为tuple对象*/
template< class U1, class U2 >
	tuple( const std::pair<U1, U2>& p );
template< class U1, class U2 >
	tuple( std::pair<U1, U2>&& p );

Example:

#include <iostream>
#include <tuple>

int main() {
    std::tuple<std::string, int> t1;    //无参构造
    std::tuple<std::string, int> t2(t1);//拷贝构造
    std::tuple<std::string, int> t3(std::make_tuple("Lily", 1));
    std::tuple<std::string, long> t4(t3);   //隐式类型转换构造的左值方式
    std::tuple<std::string, int> t5("Mike", 2); //初始化列表构造的右值方式
    std::tuple<std::string, int> t6(std::make_pair("Jack",3));  //将pair对象转换为tuple对象
    return 0;
}
2) make_tuple()函数

make_tuple() 函数以模板的形式定义在 头文件中,功能是创建一个 tuple 右值对象(或者临时对象)。

Exmaple:

	std::tuple<std::string, double ,int> t1 = std::make_tuple("Jack", 66.6, 88);
    auto t2 = std::make_tuple(1, "Lily", 'c');
//t2的类型实际是std::tuple<int, const char *, char>

②获取tuple的值

1)std::get(std::tuple)

Example:

#include <iostream>
#include <tuple>

int main() {
    auto t1 = std::make_tuple(1, "PI", 3.14);
    std::cout << '(' << std::get<0>(t1) << ',' << std::get<1>(t1) <<
            ',' << std::get<2>(t1) <<  ')' << '\n';
    return 0;
}
/*
output: (1,PI,3.14)
*/

值得注意的是,由于get的特性,tuple不支持迭代,只能通过元素索引(或tie解包)进行获取元素的值。但是给定的索引必须是在编译器就已经给定,不能在运行期进行动态传递,否则将发生编译错误

2) std::tie()

解包时,我们如果只想解某个位置的值时,可以用std::ignore占位符来表示不解某个位置的值

Example

#include <iostream>
#include <tuple>

int main() {
    auto t1 = std::make_tuple(1, "PI", 3.14);
    auto t2 = std::make_tuple(2, "MAX", 999);
    std::cout << '(' << std::get<0>(t1) << ',' << std::get<1>(t1) <<
            ',' << std::get<2>(t1) <<  ')' << '\n';
    int num = 0;
    std::string name;
    double value;
    std::tie(num, name, value) = t1;
    std::cout << '(' << num << ',' << name << ',' << value << ')' << '\n';
    num = 0, name = "", value = 0;
    std::tie(std::ignore, name, value) = t2;
    std::cout << '(' << num << ',' << name << ',' << value << ')' << '\n';
    return 0;
}
/*
output:
(1,PI,3.14)
(1,PI,3.14)
(0,MAX,999)
*/

③其他方法

1)获取元素个数

可以采用std::tuple_size<T>::value来获得,其中T必须要显式给出tuple的类型;

Example:

#include <iostream>
#include <tuple>

int main() {
    auto t1 = std::make_tuple(2, "MAX", 999, 888, 65.6);
    std::cout << "The t1 has elements: " << std::tuple_size<decltype(t1)>::value << '\n';
    return 0;
}
/*
output: The t1 has elements: 5
*/
2) 获取元素类型

可以直接采用std::tuple<size_t i,decltype(tuple)>::type来获取;

include <iostream>
#include <tuple>

int main() {
    auto t1 = std::make_tuple(2, "MAX", 999.9);
    std::cout << "The t1 has elements: " << std::tuple_size<decltype(t1)>::value << '\n';
    std::tuple_element<0, decltype(t1)>::type type0;
    std::tuple_element<1, decltype(t1)>::type type1;
    std::tuple_element<2, decltype(t1)>::type type2;
    type0 = std::get<0>(t1);
    type1 = std::get<1>(t1);
    type2 = std::get<2>(t1);
    std::cout << "type0 : " << type0 << '\n';
    std::cout << "type1 : " << type1 << '\n';
    std::cout << "type2 : " << type2 << '\n';
    return 0;
}
/*
output:
The t1 has elements: 3
type0 : 2
type1 : MAX
type2 : 999.9
*/
3)使用tuple引用来改变tuple内元素的值

std::tuple<T1&> t3(ref&); // tuple的元素类型可以是一个引用

引用声明代表对于创建tuple的对应元素而言,改变tuple的值会影响原有变量;

Example:

#include <iostream>
#include <tuple>
#include <functional>

int main() {
    auto t1 = std::make_tuple("test", 85.8, 185);
    std::string name;
    double weight;
    int height;

    auto t2 = std::make_tuple(std::ref(name), std::ref(weight),std::ref(height)) = t1;
    std::cout << "Before change : " << '\n';
    std::cout << '(' << name << ' ' << weight << ' ' << height << ')' << '\n';

    name = "spark", weight = 95.6, height = 188;
    std::cout << "After change : " << '\n';
    std::cout << '(' << std::get<0>(t2) << ' ' << std::get<1>(t2) << ' ' << std::get<2>(t2) << ')' << '\n';
    return 0;
}
/*
output:
Before change : 
(test 85.8 185)
After change : 
(spark 95.6 188)
*/

3.参考

https://cplusplus.com/reference/tuple/文章来源地址https://www.toymoban.com/news/detail-517444.html

到了这里,关于[C++] std::tuple的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 设计模式学习笔记 - 面向对象 - 1.面向对象到底讨论的是什么

    面向对象编程( OOP )的全称是 Object Oriented Programming 。 面向对象编程语言( OOPL )的全称是 Object Oriented Programming Language 。 面向对象编程中有两个非常重要的概念,就是类( Class )和对象( Object )。面向对象编程这个概念第一次使用是在 SmallTalk 这种编程语言中,它也被认

    2024年02月22日
    浏览(45)
  • Python学习笔记(二十)————面向对象

    (1)面向对象的好处 在日常中,记录数据时往往使用统一的表格,这样就不会使得数据信息格式混乱,同样在程序中的数据组织中,仅仅通过变量来记录会显得混乱不统一。 在程序中是可以做到和生活中那样,设计表格、生产表格、填写表格的组织形式的。 1. 在程序中 设

    2024年02月13日
    浏览(48)
  • Java面向对象学习笔记-4

    当编写Java程序时,了解如何处理异常是至关重要的。异常处理可以帮助我们在程序执行过程中处理各种错误情况,以确保程序能够正常运行或者 graceful 地退出。本文将介绍一些关于Java异常处理的基本概念和最佳实践,包括自定义异常类、用户输入的处理、异常捕获与处理、

    2024年02月09日
    浏览(39)
  • Java面向对象学习笔记-3

    本文将介绍Java编程中的一些基本概念和用法,包括类、接口、抽象类、继承、多态和组合等。通过代码示例,我们将深入探讨这些概念,帮助读者更好地理解如何使用Java进行面向对象编程。 Java面向对象学习笔记-1 Java面向对象学习笔记-2 我们首先来看纸张和墨盒类,它们是

    2024年02月09日
    浏览(38)
  • Java学习笔记(三):面向对象

    类(class)和对象(object, 也被称为实例 instance)是 java面向对象的核心,可以把类理解成某种概念,对象理解为一个具体存在的实体。也就是说,日常说的人,其实都是人的实例,而不是人类。 定义类的简单语法: 修饰符可以是 public、final、abstract,或者完全省略。 对一个类而

    2024年02月11日
    浏览(49)
  • Python补充笔记4-面向对象

    目录 一、编程思想​ 二、类与对象​ 三、类的创建​ 四、对象的创建​ 五、类属性、类方法、静态方法​ 六、动态绑定属性和方法​ 七、知识点总结 八、面向对象的三大特征 1.封装  2.继承​ 3.多态 九、方法重写 十、object类  十一、特殊方法和特殊属性 1.dict/len/add​

    2024年02月16日
    浏览(43)
  • 【C++】STL 算法 ⑪ ( 函数适配器嵌套用法 | modulus 函数对象 - 取模运算 | std::count_if 函数原型 | std::not1 函数原型 )

    在 functional 头文件 中 , 预定义了 modulus 函数对象 , 这是一个 二元函数对象 , 在该函数对象类中 , 重写了 函数调用操作符 函数 operator() , 该 预定义函数对象 代码如下 : 该函数对象 定义了 模板参数 template class _Ty = void , _Ty 泛型的默认参数是 void , 即 如果 不指定 模板参数 ,

    2024年01月17日
    浏览(45)
  • Lua学习笔记:面向对象的实现

    前言 本篇在讲什么 Lua中的面向对象的实现 本篇适合什么 适合 初学Lua 的小白 本篇需要什么 对 Lua 语法有简单认知 依赖 Sublime Text 编辑器 本篇的特色 具有全流程的 图文教学 重实践,轻理论,快速上手 提供全流程的 源码 内容 ★提高阅读体验★ 👉 ♣ 三级标题 👈 👉 ♦

    2024年02月13日
    浏览(47)
  • C#学习笔记--面向对象三大特征

    用程序来抽象现实世界,(万物皆对象)来编程实现功能。 三大特性:封装、继承、多态。 类与对象 声明位置: namespace 中 样式: class 类名{} 命名:帕斯卡命名法(首字母大写) 实例化对象:根据类来新建一个对象。 Person p=new Person(); 成员变量 声明在类语句块中 用来描述

    2024年02月08日
    浏览(49)
  • 《面向对象软件工程》笔记——1-2章

    “学习不仅是一种必要,而且是一种愉快的活动。” - 尼尔·阿姆斯特朗 软件工程是一门以生产出没有错误、按时并且在预算内交付的满足客户需求的软件为目的的学科。这个定义非常广泛,所以能使用到从数学、计算机科学到管理学、心理学等诸多专业的学科。开发软件的

    2024年02月06日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包