【详解】论C++的tuple
Tuple详解
定义#
std::tuple<typename, ...args>
注意需要先声明头文件 include <tuple>
或 include "tuple"
tuple
一般认为是一个不同类型元素的集合,常见用法可以用作结构体等。
基本函数#
std::get
#
template<size_t __i, typename... _Elements> constexpr __tuple_element_t<__i, tuple<_Elements...>>& get(tuple<_Elements...>& __t) noexcept { return std::__get_helper<__i>(__t); }
std::get<offset>(args)
可以返回 args
的第 offset
个元素
std::make_tuple
#
template<typename... _Elements> constexpr tuple<typename __decay_and_strip<_Elements>::__type...> make_tuple(_Elements&&... __args) { typedef tuple<typename __decay_and_strip<_Elements>::__type...> __result_type; return __result_type(std::forward<_Elements>(__args)...); }
std::make_tuple
一般表现为 std::tuple = std::make_tuple(element...)
std::tie
#
template<typename... _Elements> constexpr tuple<_Elements&...> tie(_Elements&... __args) noexcept { return tuple<_Elements&...>(__args...); }
与 std::make_tuple
相反的,可以拆分一个 std::tuple
为一堆的常量。
如果其中有不想保留的项,可以直接用 std::ignore
代替。
signed main(int argc, char *argv[]) { int a; char c; std::tuple<int, double, char> t = std::make_tuple(1, 0.1, '2'); std::tie(a, std::ignore, c) = t; std::cout << a << std::endl; // 1 std::cout << c << std::endl; // 2 return 0; }
std::forward_as_tuple
#
template<typename... _Elements> constexpr tuple<_Elements&&...> forward_as_tuple(_Elements&&... __args) noexcept { return tuple<_Elements&&...>(std::forward<_Elements(__args)...); }
用于接受右值引用数据生成 tuple
, 与 std::make_tuple
不同的是它的右值是引用的,当修改其值的时候,原来赋值所用的右值也将修改,实质上就是赋予了它地址。
注意此处 tuple
内的类型应为引用,否则相当于 std::make_tuple
。
signed main(int argc, char *argv[]) { int a = 0, c = 0; float b = 0.f, d = .1; std::tuple<int&, float&, int&, float&> tu = std::forward_as_tuple(a,b,c,d); std::get<0> (tu) = 2; std::get<1> (tu) = 4.5f; std::get<2> (tu) = 234; std::get<3> (tu) = 22.f; std::cout << a << std::endl; // 2 std::cout << b << std::endl; // 4.5 std::cout << c << std::endl; // 234 std::cout << d << std::endl; // 22 return 0; }
std::tuple_cat
#
template<typename... _Tpls, typename = typename enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type> constexpr auto tuple_cat(_Tpls&&... __tpls) -> typename __tuple_cat_result<_Tpls...>::__type { typedef typename __tuple_cat_result<_Tpls...>::__type __ret; typedef typename __make_1st_indices<_Tpls...>::__type __idx; typedef __tuple_concater<__ret, __idx, _Tpls...> __concater; return __concater::_S_do(std::forward<_Tpls>(__tpls)...); }
此函数相当与 merge
之类的,可以将若干个 tuple
合并
signed main(int argc, char *argv[]) { std::tuple<int, double> a = std::make_tuple(1, 2.5); std::tuple<char, std::string> b = std::make_tuple('c', "F**K**F"); auto c = std::tuple_cat(a, b); std::cout << std::get<0>(c) << std::endl; // 1 std::cout << std::get<1>(c) << std::endl; // 2.5 std::cout << std::get<2>(c) << std::endl; // c std::cout << std::get<3>(c) << std::endl; // F**K**F return 0; }
std::swap
#
此项不做多余解释,只是将类型相同的两个 tuple
存储的值互换
主要可以表现为
tuple1.swap(tuple2); std::swap(tuple1, tuple2);
std::tuple_size<type>::value
#
template<typename... _Elements> struct tuple_size<tuple<_Elements...>> : public integral_constant<size_t, sizeof...(_Elements)> { };
返回一个 tuple 的大小
signed main(int argc, char *argv[]) { std::tuple<int, char> t = std::make_tuple(1, 'c'); std::size_t siz = std::tuple_size<decltype(t)>::value; std::cout << siz << std::endl; // 2 }
tuple_element<I, type>::type
#
template<size_t __i, typename _Head, typename... _Tail> struct tuple_element<__i, tuple<_Head, _Tail...> > : tuple_element<__i - 1, tuple<_Tail...> > { };
返回 tuple
第 \(i\) 个元素的类型(注:从一个元素开始)
tuple<int, int, int, int> a(2, 3, 1, 4); tuple_element<1, decltype(a)>::type; // int
tuple的遍历#
由于 tuple
自身的原因,无法直接遍历,而 get<num>
中 num
必须为运行前设置好的常数
所以 tuple
的遍历需要我们手写,代码如下:
template<class Tuple, std::size_t N> struct PrintTuple { static void Print(const Tuple& value) { PrintTuple<Tuple, N - 1>::Print(value); std::cout << ' ' << std::get<N - 1>(value); return void(); } }; template<class Tuple> struct PrintTuple<Tuple, 1> { static void Print(const Tuple& value) { std::cout << std::get<0>(value); return void(); } }; template<class... Args> void TuplePrint(const std::tuple<Args...>& value) { PrintTuple<decltype(value), sizeof ...(Args)>::Print(value); }
作者: xxcxu
出处:https://www.cnblogs.com/Maraschino/p/16054162.html
本站使用「CC BY 4.0」创作共享协议,转载请在文章明显位置注明作者及出处。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报