C++代码片段(三)过滤可变模板参数中某些类型的变量
生活随笔
收集整理的這篇文章主要介紹了
C++代码片段(三)过滤可变模板参数中某些类型的变量
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
將可變模板參數列表中的某些類型過濾掉,然后返回剩下數據的元組。用到了上一篇中的判斷可變模板參數中是否包含某一特定類型的方法
#include <iostream> #include <tuple> #include <string> #include <vector> #include <list>template <typename T, typename... Args> struct contains : public std::false_type {};template <typename T, typename U, typename... Args> struct contains<T, U, Args...> :public std::conditional_t<std::is_same_v<T, U>, std::true_type, contains<T, Args...>> {};template <typename... FilterArgs> struct type_filter {static constexpr auto filter() { return std::tuple{}; }template <typename T, typename... Args>static constexpr auto filter(T&& t, Args&&... args) {using type = std::remove_reference_t<T>;if constexpr (contains<type, FilterArgs...>::value) {return filter(std::forward<Args>(args)...);}else {return std::tuple_cat(std::make_tuple(std::forward<T>(t)), filter(std::forward<Args>(args)...));}} };實現原理
相當于依次遍歷可變模板參數列表中的數據,每次遍歷時判斷數據的類型是否是想要過濾掉的類型(也就是判斷當前類型是否存在于過濾類型中),如果是則丟棄當前數據繼續遍歷,否則保留數據
沒有過濾掉的數據保存在元組中,采用std::tuple_cat方法將兩個std::tuple連接成一個
std::tuple<int, double> t1{ 10, 2.5 }; std::tuple<std::string> t2{ "abc" }; auto t = std::tuple_cat(t1, t2); // decltype(t) = std::tuple<int, double, std::string>需要注意的問題
過濾函數filter的聲明為
template <typename T, typename... Args> static constexpr auto filter(T&& t, Args&&... args);接收的參數類型是T&&,所以分成兩種情況討論(假設傳入的類型是int)
- 傳入的t是左值引用類型int&,則T會被推導成int&,由于引用疊加效果,int&&& => int&
- 傳入的t是右值引用類型int&&,則T會被推導成int,不存在引用疊加效果,int&& => int&&
而在調用contains
if constexpr (std::is_same_v<int&, int>) {std::cout << "int& is same as int\n"; } else {std::cout << "int& is different from int\n"; }// 輸出:int& is different from int所以需要在調用contains之前去掉類型T上面的引用屬性,使用標準庫實現
std::remove_reference_t<T>測試程序
#include <iostream> #include <tuple> #include <string> #include <vector> #include <list>template <typename T, typename... Args> struct contains : public std::false_type {};template <typename T, typename U, typename... Args> struct contains<T, U, Args...> :public std::conditional_t<std::is_same_v<T, U>, std::true_type, contains<T, Args...>> {};template <typename... FilterArgs> struct type_filter {static constexpr auto filter() { return std::tuple{}; }template <typename T, typename... Args>static constexpr auto filter(T&& t, Args&&... args) {using type = std::remove_reference_t<T>;if constexpr (contains<type, FilterArgs...>::value) {return filter(std::forward<Args>(args)...);}else {return std::tuple_cat(std::make_tuple(std::forward<T>(t)), filter(std::forward<Args>(args)...));}} };template <typename Tuple, typename Func, std::size_t... Idx> void for_each(Tuple&& t, Func&& f, std::index_sequence<Idx...>) {(f(std::get<Idx>(t)), ...); }template <typename... Args> void filter_test(Args&&... args) {auto t = type_filter<int, std::list<std::string>, std::vector<int>>::filter(std::forward<Args>(args)...);for_each(t, [](auto& item) {std::cout << item << std::endl;}, std::make_index_sequence<std::tuple_size_v<decltype(t)>>{}); }int main() {// l被推導為左值引用std::list<std::string>&// n被推導為左值引用int&// 字面值常量"abc", 20, 2.5被推導為右值引用std::string&&, int&&, double&&// vector被推導為右值引用std::vector<int>&&std::list<std::string> l{ "abc", "def", "123" };int n = 10;filter_test(l, "abc", n, 20, 2.5, std::vector<int>{1, 2, 3});return 0; } 與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的C++代码片段(三)过滤可变模板参数中某些类型的变量的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 解决无法将自己github上的代码clo
- 下一篇: 解决MySQL使用LOAD导入中文数据乱