日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++代码片段(五)tuple的实现

發布時間:2024/4/19 c/c++ 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++代码片段(五)tuple的实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

元組tuple是多類型的集合,可以當做升級版的pair來用。因為tuple可以保存多個任意類型的值,導致不能夠在一個類里面保存所有的數據,所以采用每一層保存一個數據的方法實現

實現tuple

template <typename... Args> class tuple { };/* 每一層保存一個T類型的數據 */ template <typename T, typename... Args> class tuple<T, Args...> : public tuple<Args...> {public:tuple() = default;tuple(T&& t, Args&&... args): tuple<Args...>(std::forward<Args>(args)...),value_(std::forward<T>(t)){ }template <std::size_t N>decltype(auto) get() {static_assert(N<=sizeof...(Args));if constexpr (N == 0) {return (value_);}else {return (this->tuple<Args...>::template get<N - 1>());}}template <std::size_t N>decltype(auto) get() const {static_assert(N<=sizeof...(Args));if constexpr (N == 0) {return (value_);}else {return (this->tuple<Args...>::template get<N - 1>());}}protected:T value_; };

實現tuple_element

tuple_element<N, Tuple>萃取元組Tuple的第N個類型。依次遍歷每一個模板參數,直到遍歷到第N個后返回,采用繼承的方式保證最外層的tuple_element_helper可以獲取最終的結果

模板的模板參數用來偏特化元組類型,目的是萃取出參數列表

template <std::size_t N, template <typename...> class Tuple, typename... ArgsWrapper> struct tuple_element<N, Tuple<ArgsWrapper...>> {template <std::size_t M, typename T, typename... Args>struct tuple_element_helper : public tuple_element_helper<M-1, Args..., void>{};template <typename T, typename... Args>struct tuple_element_helper<0, T, Args...>{using type = T;};using type = typename tuple_element_helper<N, ArgsWrapper..., void>::type; };template <std::size_t N, typename Tuple> using tuple_element_t = typename tuple_element<N, Tuple>::type;

實現tuple_size

tuple_size<Tuple>萃取元組Tuple中包含的數據個數。直接利用模板的模板參數萃取參數列表,然后使用sizeof計算參數列表的個數即可

template <typename Tuple> struct tuple_size : public std::integral_constant<std::size_t, 0> { };template <template <typename...> class Tuple, typename... Args> struct tuple_size<Tuple<Args...>> : public std::integral_constant<std::size_t, sizeof...(Args)> { };template <typename Tuple> static constexpr inline auto tuple_size_v = tuple_size<Tuple>::value;

實現make_tuple

make_tuple根據參數創建tuple,引用cppreference上面的標準介紹

創建 tuple 對象,從參數類型推導目標類型。

對于每個 Types... 中的 Ti , Vtypes... 中的對應類型 Vi 為 std::decay::type ,除非應用 std::decay 對某些類型 X 導致 std::reference_wrapper ,該情況下推導的類型為 X& 。

decay會移除類型的const和volatile限定符以及引用,將左值轉換成右值,但是對于reference_wrapper類型需要特殊處理,保證tuple的模板參數也同樣是引用包裝器

namespace detail {template <typename T>struct unwrap_refwrapper{using type = T;};template <typename T>struct unwrap_refwrapper<std::reference_wrapper<T>>{using type = T&;};template <typename T>using special_decay_t = typename unwrap_refwrapper<std::decay_t<T>>::type; }template <typename... Args> tuple<Args...> make_tuple(Args&&... args) {return tuple<detail::special_decay_t<Args>...>(std::forward<Args>(args)...); }

實現tuple_cat

tuple_cat用于將兩個tuple連接起來,依次將每個tuple的數據取出放到可變模板參數列表中,最后重新組裝即可

namespace detail {template <std::size_t N1, std::size_t M1, std::size_t N2, std::size_t M2, typename Tuple1, typename Tuple2, typename... Args>auto tuple_cat_impl(Tuple1&& t1, Tuple2&& t2, Args&&... args) {if constexpr (N1 == M1 && N2 == M2) {return make_tuple(std::forward<Args>(args)...);}else if constexpr (N1 == M1) {return tuple_cat_impl<N1, M1, N2+1, M2>(std::forward<Tuple1>(t1),std::forward<Tuple2>(t2),std::forward<Args>(args)...,t2.template get<N2>());}else {return tuple_cat_impl<N1+1, M1, N2, M2>(std::forward<Tuple1>(t1),std::forward<Tuple2>(t2),std::forward<Args>(args)...,t1.template get<N1>());}} } template <typename... Args1, typename... Args2> auto tuple_cat(const tuple<Args1...>& t1, const tuple<Args2...>& t2) {return detail::tuple_cat_impl<0, sizeof...(Args1), 0, sizeof...(Args2)>(t1, t2); }

總結

以上是生活随笔為你收集整理的C++代码片段(五)tuple的实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。