1.元组简介
tuple是一个固定大小的不同类型值的集合,是泛化的std::pair。我们也可以把他当做一个通用的结构体来用,不需要创建结构体又获取结构体的特征,在某些情况下可以取代结构体使程序更简洁,直观。std::tuple理论上可以有无数个任意类型的成员变量,而std::pair只能是2个成员,因此在需要保存3个及以上的数据时就需要使用tuple元组了。
tuple(元组)在c++11中开始引用的。tuple看似简单,其实它是简约而不简单,可以说它是c++11中一个既简单又复杂的东东,关于它简单的一面是它很容易使用,复杂的一面是它内部隐藏了太多细节,要揭开它神秘的面纱时又比较困难。
2.tuple的创建以及初始化
std::string name;
std::tuple<string &, int> tpRef(name, 30);
// 对tpRef第一个元素赋值,同时name也被赋值 – 引用
std::get<0>(tpRef) = “Sven”;
// name输出也是Sven
std::cout << “name: ” << name << ‘\n’;
3.有关tuple的操作
3.1等价结构体
开篇讲过在某些时候tuple可以等同于结构体一样使用,这样既方便又快捷。如
struct person {
char *m_name;
char *m_addr;
int *m_ages;
};
//可以用tuple来表示这样的一个结构类型,作用是一样的。
std::tuple<const char *, const char *, int>
3.2获取元组取个数和合并元组
tuple_size<decltype(u)>::value;
tuple_cat;
#include<tuple>
#include<iostream>
int main()
{
std::tuple<double,char,std::string> u(2.6,'c',"王五");
std::cout<<std::tuple_size<decltype(u)>::value<<std::endl;
std::tuple<double,char,std::string> v(1.6,'d',"陈六");
auto new_tuple=std::tuple_cat(std::move(u),std::move(v));
std::cout<<std::get<5>(new_tuple)<<"\n";
}
3.3获取元组类型
std::tuple<std::string, int> tp("Sven", 20);
// 得到第二个元素类型
std::tuple_element<1, decltype(tp)>::type ages; // ages就为int类型
ages = std::get<1>(tp);
std::cout << "ages: " << ages << '\n';
//输出结果:
ages: 20
3.4解包和引用
#include<tuple>
#include<iostream>
#include<variant>
auto get_student(int id)
{
if(id==0)
return std::make_tuple(3.8,'A',"张三");
if(id==1)
return std::make_tuple(3.3,'c',"李四");
if(id==2)
return std::make_tuple(2.9,'d',"王五");
return std::make_tuple(0.0,'D',"null");
}
int main()
{
auto student=get_student(0);
std::cout << "ID: 0, "
<< "GPA: " << std::get<0>(student) << ", "
<< " 成绩: " << std::get<1>(student) << ", "
<< " 姓名: " << std::get<2>(student) << '\n';
double gpa;
char grade;
std::string name;
std::tie(gpa,grade,name)=get_student(1);
std::cout << "ID: 1, "
<< "GPA: " << gpa << ", "
<< " 成绩: " << grade << ", "
<< " 姓名: " << name << "\n";
}
//output
ID: 0, GPA: 3.8, 成绩: A, 姓名: 张三
ID: 1, GPA: 3.3, 成绩: c, 姓名: 李四
但有时候tuple包含的多个元素时只需要其中的一个或两个元素,如此可以通过std::ignore进行变量占位,这样将会忽略提取对应的元素
#include <iostream>
#include <tuple>
#include <utility>
int main(int argc, char **argv) {
std::tuple<std::string, int, std::string, int> tp;
tp = std::make_tuple("Sven", 25, "Shanghai", 21);
// 定义接收变量
std::string name;
std::string addr;
int ages;
int areaCode = 110;
std::tie(name, ages, std::ignore, std::ignore) = tp;
std::cout << "Output: " << '\n';
std::cout << "name: " << name <<", ";
std::cout << "addr: " << addr << ", ";
std::cout << "ages: " << ages << ", ";
std::cout << "areaCode: " << areaCode << '\n';
return 0;
}
//输出结果:
Output:
name: Sven, addr: , ages: 25, areaCode: 110
3.5遍历
tuple不支持迭代,只能通过元素索引(或tie解包)进行获取元素的值。但是给定的索引必须是在编译器就已经给定,不能在运行期进行动态传递,否则将发生编译错误:
tuple不支持迭代,只能通过元素索引(或tie解包)进行获取元素的值。但是给定的索引必须是在编译器就已经给定,不能在运行期进行动态传递,否则将发生编译错误:
正确遍历:
// 帮助程序用于将元组转换为可变参数模板函数参数
// sequence_generator<3>::type will be sequence<0, 1, 2>.
template <int...>
struct sequence {};
template <int N, int... S>
struct sequence_generator : sequence_generator<N - 1, N - 1, S...> {};
template <int... S>
struct sequence_generator<0, S...> {
typedef sequence<S...> type;
};
template<typename T, typename F, int... S>
void for_each(T&& t, F f, sequence<S...>)
{
auto l = { (f(std::get<S>(t)), 0)... };
}
template<typename... Args, typename F>
void for_each_in_tuple(std::tuple<Args...> const& t, F f)
{
for_each(t, f, typename sequence_generator<sizeof...(Args)>::type());
}
struct functor {
template<typename T>
void operator()(T&& t)
{
std::cout << t << std::endl;
}
};
int main()
{
std::tuple<double, char, std::string> t = std::make_tuple(3.14, 'A', "StoneLiu");
for_each_in_tuple(t, functor());
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/129689.html