tuple 简易实现(C++ 模板元编程)

编程入门 行业动态 更新时间:2024-10-25 04:23:06

tuple <a href=https://www.elefans.com/category/jswz/34/1769136.html style=简易实现(C++ 模板元编程)"/>

tuple 简易实现(C++ 模板元编程)

std::tuple

在标准库里面,tuple主要有下面四个类模板 or 函数模板

  • tuple
  • tuple_size
  • tuple_element
  • get

在后续有实现:tuple_size_v = tuple_size::valuetuple_element_t = tuple_element::type

事例Example:

auto tup = std::tuple<int, float, double, std::string>(0, 1.0, 2.0, "aaa");
std::cout << std::get<0>(tup) << " " << std::get<1>(tup)<< " " << std::get<2>(tup) << " " << std::get<3>(tup) << "\n";std::cout << std::tuple_size<decltype(tup)>::value << "\n";
std::cout << std::tuple_size_v<decltype(tup)> << "\n";std::tuple_element<3, decltype(tup)>::type a = "aaa";
std::cout << a << "\n";
std::tuple_element_t<3, decltype(tup)> b = "aaa";
std::cout << b << "\n";

sample:tuple

tuple

仿造stl:tuple的实现,采用模板递归继承的方式:

template<typename ...Ts> struct tuple;template<typename T> struct tuple<T> {using type = tuple;using value_type = T;T value_;
};template<typename T, typename ...Ts> struct tuple<T, Ts...> {using type = tuple;using value_type = T;using super_type = tuple<Ts...>;T value_;super_type rest_;
};

添加构造函数

template<typename Tv>
requires std::is_same_v<std::decay_t<Tv>, T>
tuple(Tv&& value) : value_(std::forward<Tv>(value)) {}
template<typename Tv, typename ...Tvs>
requires std::is_same_v<std::decay_t<Tv>, T>
tuple(Tv&& value, Tvs&& ...rest): value_(std::forward<Tv>(value)),rest_(super_type(std::forward<Tvs>(rest)...)) {}

test:

const std::string str1 = "lifehappy";
tuple<int, float, double, std::string> a1(114514, 114.514f, 114.514, std::move(str1));
std::cout << a1.value_ << " " << a1.rest_.value_ << " " << a1.rest_.rest_.value_ << " " << a1.rest_.rest_.rest_.value_ << "\n";
std::cout << str1 << " str1\n";std::string str2 = "lifehappy";
tuple<int, float, double, std::string> a2(114514, 114.514f, 114.514, std::move(str2));
std::cout << a2.value_ << " " << a2.rest_.value_ << " " << a2.rest_.rest_.value_ << " " << a2.rest_.rest_.rest_.value_ << "\n";
std::cout << str2 << " str2\n";

114514 114.514 114.514 lifehappy
lifehappy str1
114514 114.514 114.514 lifehappy
str2

为了让大家方便访问tuple里的内容,并没有采用继承的方式实现,但是,在后续的类模板中,均套用一下tuple类模板:

template<typename ...Ts> struct tuple;template<typename T> struct tuple<T> {using type = tuple;using value_type = T;T value_;template<typename Tv>requires std::is_same_v<std::decay_t<Tv>, T>tuple(Tv&& value) : value_(std::forward<Tv>(value)) {}tuple() {}~ tuple() {}
};template<typename T, typename ...Ts> struct tuple<T, Ts...> : tuple<Ts...> {using type = tuple;using value_type = T;using super_type = tuple<Ts...>;T value_;template<typename Tv, typename ...Tvs>requires std::is_same_v<std::decay_t<Tv>, T>tuple(Tv&& value, Tvs&& ...rest): value_(std::forward<Tv>(value)),super_type(std::forward<Tvs>(rest)...) {}tuple() {}~ tuple() {}
};

tuple_size

template<typename T> struct tuple_size {};template<typename ...Ts>
struct tuple_size<tuple<Ts...>> : std::integral_constant<int, sizeof...(Ts)> {};template<typename T>
constexpr static int tuple_size_v = tuple_size<T>::value;

tuple_element

template<int N, typename T> struct tuple_element {};template<int N, typename ...Ts>
struct tuple_element<N, tuple<Ts...>> : tuple_element<N - 1, typename tuple<Ts...>::super_type> {};template<typename ...Ts>
struct tuple_element<0, tuple<Ts...>> { using type = tuple<Ts...>::value_type; };template<int N, typename T>
using tuple_element_t = tuple_element<N, T>::type;

get

由于继承,所以可以通过static_cast<T>(tuple)T必须是满足条件的某个基类,那么先要实现一个获得第几代父亲类型的类模板:

template<int N, typename T> struct tuple_type_impl {};template<int N, typename ...Ts>
struct tuple_type_impl<N, tuple<Ts...>>: tuple_type_impl<N - 1, typename tuple<Ts...>::super_type> {};template<typename ...Ts>
struct tuple_type_impl<0, tuple<Ts...>> {using type = tuple<Ts...>::type;
};template<int N, typename T>
using tuple_type = tuple_type_impl<N, T>::type;

接着就可以通过static_cast得到其对应的类型value了:

template<int N, typename ...Ts>
auto&& get(tuple<Ts...> &tup) {using type = tuple_type<N, tuple<Ts...>>;return static_cast<type&>(tup).value_;
}

完整代码

#include <iostream>
#include <type_traits>template<typename ...Ts> struct tuple;template<typename T> struct tuple<T> {using type = tuple;using value_type = T;T value_;template<typename Tv>requires std::is_same_v<std::decay_t<Tv>, T>tuple(Tv&& value) : value_(std::forward<Tv>(value)) {}tuple() {}~ tuple() {}
};template<typename T, typename ...Ts> struct tuple<T, Ts...> : tuple<Ts...> {using type = tuple;using value_type = T;using super_type = tuple<Ts...>;T value_;template<typename Tv, typename ...Tvs>requires std::is_same_v<std::decay_t<Tv>, T>tuple(Tv&& value, Tvs&& ...rest): value_(std::forward<Tv>(value)),super_type(std::forward<Tvs>(rest)...) {}tuple() {}~ tuple() {}
};template<typename T> struct tuple_size {};template<typename ...Ts>
struct tuple_size<tuple<Ts...>> : std::integral_constant<int, sizeof...(Ts)> {};template<typename T>
constexpr static int tuple_size_v = tuple_size<T>::value;template<int N, typename T> struct tuple_element {};template<int N, typename ...Ts>
struct tuple_element<N, tuple<Ts...>> : tuple_element<N - 1, typename tuple<Ts...>::super_type> {};template<typename ...Ts>
struct tuple_element<0, tuple<Ts...>> { using type = tuple<Ts...>::value_type; };template<int N, typename T>
using tuple_element_t = tuple_element<N, T>::type;template<int N, typename T> struct tuple_type_impl {};template<int N, typename ...Ts>
struct tuple_type_impl<N, tuple<Ts...>>: tuple_type_impl<N - 1, typename tuple<Ts...>::super_type> {};template<typename ...Ts>
struct tuple_type_impl<0, tuple<Ts...>> {using type = tuple<Ts...>::type;
};template<int N, typename T>
using tuple_type = tuple_type_impl<N, T>::type;template<int N, typename ...Ts>
auto&& get(tuple<Ts...> &tup) {using type = tuple_type<N, tuple<Ts...>>;return static_cast<type&>(tup).value_;
}int main() {const std::string str1 = "lifehappy";tuple<int, float, double, std::string> a1(114514, 114.514f, 114.514, std::move(str1));// std::cout << a1.value_ << " " << a1.rest_.value_ << " " << a1.rest_.rest_.value_ << " " << a1.rest_.rest_.rest_.value_ << "\n";// std::cout << str1 << " str1\n";std::string str2 = "lifehappy";tuple<int, float, double, std::string> a2(114514, 114.514f, 114.514, std::move(str2));// std::cout << a2.value_ << " " << a2.rest_.value_ << " " << a2.rest_.rest_.value_ << " " << a2.rest_.rest_.rest_.value_ << "\n";// std::cout << str2 << " str2\n";std::cout << tuple_size_v<decltype(a1)> << " " << tuple_size<decltype(a2)>::value << "\n";std::cout << std::is_same_v<tuple_element<0, decltype(a1)>::type, tuple_element_t<0, decltype(a1)>> << " "<< std::is_same_v<tuple_element<1, decltype(a1)>::type, tuple_element_t<1, decltype(a1)>> << " "<< std::is_same_v<tuple_element<2, decltype(a1)>::type, tuple_element_t<2, decltype(a1)>> << " "<< std::is_same_v<tuple_element<3, decltype(a1)>::type, tuple_element_t<3, decltype(a1)>> << "\n";std::cout << get<0>(a1) << " " << get<1>(a1) << " "<< get<2>(a1) << " " << get<3>(a1) << "\n";get<0>(a2) = 415411;std::cout << get<0>(a2) << " " << get<1>(a2) << " "<< get<2>(a2) << " " << get<3>(a2) << "\n";return 0;
}

4 4
1 1 1 1
114514 114.514 114.514 lifehappy
415411 114.514 114.514 lifehappy

更多推荐

tuple 简易实现(C++ 模板元编程)

本文发布于:2023-11-17 01:49:45,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1637644.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:简易   模板   tuple

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!