【详解】论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