您当前的位置:首页 > 计算机 > 编程开发 > C语言

深入 C 元组 tuple 实现

时间:12-14来源:作者:点击数:

什么是 tuple

using Person = tuple<std::string, char, int>;
Person john { "John"s, 'M', 21 }; Person jess { "Jess"s, 'F', 19 };
Person jack = make_tuple("Jack"s, 'M', 20);
std::string john_name = get<0>(john); int jess_age = get<int>(jess);
char gender_jack; tie(ignore, gender_jack, ignore) = jack; 

什么是 tuple

std::set<Person> group { john, jess, jack };
using Hobby = tuple<std::string, int>;
Hobby kongfu { "Kong Fu", 2 };
auto john_hobby = tuple_cat(john, kongfu); 

什么是 tuple

Reference:  github /BOT-Man-JL/ORM-Lite

 auto usersOrderList = mapper.Query(userModel) .Join(userModel, field(userModel.user_id) == field(orderModel.user_id) ).ToList(); 

存储实现

template <typename... Types> class tuple : Types... {}; 
  • 错误: tuple<int> : int

存储实现

template <typename T> struct _t_leaf { T _val; };
template <typename... Types> class tuple : _t_leaf<Types>... {}; 
  • 错误: tuple<int, int>
  • 错误: tuple<int, double> == tuple<double, int>

存储实现

template <> class tuple<> {}; template <typename Head, typename... Tails>
class tuple<Head, Tails...> { Head _head; tuple<Tails...> _tails; }; 
  • sizeof(tuple<int>) >= sizeof(int) + 1
  • 阻止 EBO (Empty Base Optimization)( en.cppreference 商业网/w/cpp/language/ebo)

存储实现

template <> class tuple<> {}; template <typename Head, typename... Tails>
class tuple<Head, Tails...> : tuple<Tails...> { Head _head; }; 
  • sizeof(tuple<int, Empty>) >= sizeof(int) + 1
  • 但 C++ 20 可用 [[no_unique_address]]( en.cppreference 商业网/w/cpp/language/attributes/no_unique_address) 代替 EBO
  • 参考: msvc( github /microsoft/STL/blob/39eb812426167fc7955005b53b28d696c50e8b61/stl/inc/tuple)

存储实现

template <size_t, typename T, bool = std::is_empty_v<T> && !std::is_final_v<T>> struct _t_leaf { T _val; };
template <size_t I, typename T> struct _t_leaf<I, T, false> { T _val; };
template <size_t I, typename T> struct _t_leaf<I, T, true> : private T {}; 
  • 参考: libc++( github /llvm/llvm-project/blob/691eb814c1ae38d5015bf070dfed3fd54d542582/libcxx/include/tuple) / libstdc++( github /gcc-mirror/gcc/blob/f0c0f124ebe28b71abccbd7247678c9ac608b649/libstdc++-v3/include/std/tuple)

存储实现

template <typename S, typename... Ts> struct _t_impl;
template <size_t... Is, typename... Ts> struct _t_impl<std::index_sequence<Is...>, Ts...> : _t_leaf<Is, Ts>... {}; template <typename... Ts> class tuple : _t_impl< std::make_index_sequence<sizeof...(Ts)>, Ts...> {}; 
  • 参考: libc++( github /llvm/llvm-project/blob/691eb814c1ae38d5015bf070dfed3fd54d542582/libcxx/include/tuple)

存储实现

template <size_t Idx, typename... Ts> struct _t_impl; template <size_t Idx> struct _t_impl<Idx> {};
template <size_t Idx, typename Head, typename... Tails> struct _t_impl<Idx, Head, Tails...> : _t_impl<Idx + 1, Tails...>, _t_leaf<Idx, Head> {}; template <typename... Ts> class tuple : _t_impl<0, Ts...> {}; 
  • 参考: libstdc++( github /gcc-mirror/gcc/blob/f0c0f124ebe28b71abccbd7247678c9ac608b649/libstdc++-v3/include/std/tuple)

构造函数

 tuple(); tuple(const Head&, const Tails&...); template <typename T, typename... Ts> tuple(T&& arg, Ts&& ...args);
template <typename... Rhs> tuple(const tuple<Rhs...>& rhs); template <typename... Rhs> tuple(tuple<Rhs...>&& rhs); tuple(const tuple&); tuple(tuple&&); 

构造函数

template <typename T, typename... Ts> tuple(T&& arg, Ts&& ...args) : Tail(std::forward<Ts>(args)...), _val(std::forward<T>(arg)) {}
template <typename... Rhs> tuple(tuple<Rhs...>&& rhs) : Tail(std::move(rhs._tail())), _val(std::move(rhs._head())) {} 

构造函数

 tuple<int> t(tuple<int> { 1 }); 
  • 引入模板匹配错误 SFINAE + is_convertible
  • 值转换方式声明为 explicit

构造函数

 template <typename T, typename... Ts, typename = std::enable_if_t< std::is_convertible_v<T, Head> > > explicit tuple(T&& arg, Ts&& ...args) : Tail(std::forward<Ts>(args)...), _val(std::forward<T>(arg)) {} 

tuple_element & get

template <size_t I, typename Tuple> struct tuple_element; template <size_t I, typename... Ts> tuple_element<I, tuple<Ts...>>::type& get( tuple<Ts...>&); 

tuple_element & get

template<size_t I, typename T, typename... Ts> struct tuple_element<I, tuple<T, Ts...>> : tuple_element<I - 1, tuple<Ts...>> {};
template <typename T, typename... Ts> struct tuple_element<0, tuple<T, Ts...>> { using type = T; using _tuple = tuple<T, Ts...>; }; 

tuple_element & get

template <size_t I, typename...Ts> tuple_element<I, tuple<Ts...>>::type& get( tuple<Ts...>& t) {
return ((tuple_element<I, tuple<Ts...>>:: _tuple&) t)._val;
} 

更多内容

  • tuple_size
  • operator== / operator<
  • get (by type)
  • swap
  • make_tuple / tie / forward_as_tuple / tuple_cat
感悟
  • 严谨的推导
  • 语言工具的最小正交
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐