C++ 自定义遍历stl容器元素函数print

    刷题debug的时候经常会需要打印stl容器里的元素,每次打印都要写一堆for循环,打印栈或者队列的时候还不能用for循环遍历,还要注意换行等等内容保证打印出来的东西自己能看懂,感觉很麻烦,于是写了一个类似python的可以直接打印出列表、元组、字典等所有元素print函数,编译参数加上C++17,源码如下:

/**
  ******************************************************************************
  * @file           : my_stl_print.h
  * @author         : Mr.Yi
  * @brief          : 简化打印stl容器中的数据
  * @attention      : None
  * @date           : 2023/4/30
  ******************************************************************************
  */

#pragma once

#include <iostream>
#include <vector>
#include <string>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>

template <class T>
struct is_pair {
private:
    template <class U, class V>
    [[maybe_unused]] static std::true_type test(const std::pair<U,V> &) { return {}; }
    static std::false_type test(...) { return {}; }

public:
    static constexpr bool value = decltype(test(std::declval<T>()))::value;
};

template <class T>
struct is_vector {
private:
    template <class U>
    [[maybe_unused]] static std::true_type test(const std::vector<U> &) { return {}; }
    static std::false_type test(...) { return {}; }

public:
    static constexpr bool value = decltype(test(std::declval<T>()))::value;
};

template <class T>
struct is_list {
private:
    template <class U>
    [[maybe_unused]] static std::true_type test(const std::list<U> &) { return {}; }
    static std::false_type test(...) { return {}; }

public:
    static constexpr bool value = decltype(test(std::declval<T>()))::value;
};

template <class T>
struct is_deque {
private:
    template <class U>
    [[maybe_unused]] static std::true_type test(const std::deque<U> &) { return {}; }
    static std::false_type test(...) { return {}; }

public:
    static constexpr bool value = decltype(test(std::declval<T>()))::value;
};

template <class T>
struct is_queue {
private:
    template <class U>
    [[maybe_unused]] static std::true_type test(const std::queue<U> &) { return {}; }
    static std::false_type test(...) { return {}; }

public:
    static constexpr bool value = decltype(test(std::declval<T>()))::value;
};

template <class T>
struct is_priority_queue {
private:
    template <class U>
    [[maybe_unused]] static std::true_type test(const std::priority_queue<U> &) { return {}; }
    template<class U, class Container, class Compare>
    [[maybe_unused]] static std::true_type test(const std::priority_queue<U, Container, Compare> &) { return {}; }
    static std::false_type test(...) { return {}; }

public:
    static constexpr bool value = decltype(test(std::declval<T>()))::value;
};

template <class T>
struct is_stack {
private:
    template <class U>
    [[maybe_unused]] static std::true_type test(const std::stack<U> &) { return {}; }
    static std::false_type test(...) { return {}; }

public:
    static constexpr bool value = decltype(test(std::declval<T>()))::value;
};

template <class T>
struct is_set {
private:
    template <class U, class V>
    [[maybe_unused]] static std::true_type test(const std::set<U, V> &) { return {}; }
    template <class U, class V>
    [[maybe_unused]] static std::true_type test(const std::multiset<U, V> &) { return {}; }
    template <class U, class V>
    [[maybe_unused]] static std::true_type test(const std::unordered_set<U, V> &) { return {}; }
    template <class U, class V>
    [[maybe_unused]] static std::true_type test(const std::unordered_multiset<U, V> &) { return {}; }
    static std::false_type test(...) { return {}; }

public:
    static constexpr bool value = decltype(test(std::declval<T>()))::value;
};

template <class T>
struct is_map {
private:
    template <class U, class V>
    [[maybe_unused]] static std::true_type test(const std::map<U, V> &) { return {}; }
    template <class U, class V>
    [[maybe_unused]] static std::true_type test(const std::multimap<U, V> &) { return {}; }
    template <class U, class V>
    [[maybe_unused]] static std::true_type test(const std::unordered_map<U, V> &) { return {}; }
    template <class U, class V>
    [[maybe_unused]] static std::true_type test(const std::unordered_multimap<U, V> &) { return {}; }
    static std::false_type test(...) { return {}; }

public:
    static constexpr bool value = decltype(test(std::declval<T>()))::value;
};

template <class T>
inline constexpr bool is_pair_v = is_pair<T>::value;

template <class T>
inline constexpr bool is_vector_v = is_vector<T>::value;

template <class T>
inline constexpr bool is_list_v = is_list<T>::value;

template <class T>
inline constexpr bool is_deque_v = is_deque<T>::value;

template <class T>
inline constexpr bool is_queue_v = is_queue<T>::value;

template <class T>
inline constexpr bool is_priority_queue_v = is_priority_queue<T>::value;

template <class T>
inline constexpr bool is_stack_v = is_stack<T>::value;

template <class T>
inline constexpr bool is_set_v = is_set<T>::value;

template <class T>
inline constexpr bool is_map_v = is_map<T>::value;

template <class T>
inline constexpr bool is_stl_container = is_pair_v<T> || is_vector_v<T> || is_list_v<T> || is_deque_v<T> \
|| is_queue_v<T> || is_priority_queue_v<T> || is_stack_v<T> || is_set_v<T> || is_map_v<T>;

template <class T, size_t N>
void print(T (&arr)[N]) {
    for (int i = 0; i < N; i++) 
        std::cout << arr[i] << " ";
    std::cout << "\n";
}

template <class T, size_t M, size_t N>
void print(T (&arr)[M][N]) {
    for (int i = 0; i < M; i++) {
        for (int j = 0; j < N; j++) 
            std::cout << arr[i][j] << " ";
        std::cout << "\n";
    }
    std::cout << "\n";
}

template <class T>
void print ([[maybe_unused]] const T& container) noexcept {
    if constexpr(is_pair_v<decltype(container)>) {
        std::cout << container.first << " " << container.second << "\n";
    } else if constexpr (is_deque_v<decltype(container)> || is_vector_v<decltype(container)> \
                || is_list_v<decltype(container)> || is_set_v<decltype(container)>) {
        for ([[maybe_unused]] const auto &value: container)
            if constexpr (is_stl_container<decltype(value)>)
                print(value);
            else
                std::cout << value << " ";
    } else if constexpr (is_stack_v<decltype(container)> || is_priority_queue_v<decltype(container)>) {
        auto tmp = container;
        while (!tmp.empty()) {
            [[maybe_unused]] auto top = tmp.top();
            tmp.pop();
            if constexpr (is_stl_container<decltype(top)>)
                print(top);
            else
                std::cout << top << " ";
        }
    } else if constexpr (is_queue_v<decltype(container)>) {
        auto tmp = container;
        while (!tmp.empty()) {
            [[maybe_unused]] auto front = tmp.front();
            tmp.pop();
            if constexpr (is_stl_container<decltype(front)>)
                print(front);
            else
                std::cout << front << " ";
        }
    } else if constexpr (is_map_v<decltype(container)>) {
        for ([[maybe_unused]] const auto& [v, k] : container) {
            if constexpr (is_stl_container<decltype(k)>) {
                std::cout << "v: " << v << " k: ";
                print(k);
            }
            else
                std::cout << "v: " << v << " k: " << k << "\n";
        }
    } else {
        std::cout << container;
    }
    if constexpr (!is_pair_v<decltype(container)>)
        std::cout << "\n";
}

测试代码如下,可简单验证元素顺序正确性:

namespace my_test_stl_print {
    void test_vector () {
        vector<int> v1 {1, 2, 3, 4, 5};
        vector<string> v2 {"123", "234", "asd", "zxc"};
        vector<vector<int>> v3 {{1,2,3},{4,5,6}, {7,8,9}};
        vector<vector<string>> v4 {{"123", "234", "345"}, {"234", "345", "456"}};
        vector<pair<int,int>> v5 {{1,2}, {2,3}, {3,4}};
        vector<vector<vector<int>>> v6 {{{1,2,3} ,{4,5,6}}, {{7,8,9}, {10,11,12}}, {{13,14,15}} };
        vector<list<int>> v7 {{1,2,3}, {4,5,6}};
        vector<deque<int>> v8 {{1,2,3}, {4,5,6}};
        vector<set<int>> v9 {{1,2,1,3}, {4,5,6,6}};
        print(v1);
        print(v2);
        print(v3);
        print(v4);
        print(v5);
        print(v6);
        print(v7);
        print(v8);
        print(v9);

        vector<vector<int>> v10;
        for (int i = 0; i < 100; i++) {
            vector<int> tmp;
            for (int j = 0; j < 20; j++)
                tmp.emplace_back(j);
            v10.emplace_back(tmp);
        }

        print(v10);
    }
    void test_list () {
        list<int> l1 {1, 2, 3, 4, 5};
        list<string> l2 {"123", "234", "asd", "zxc"};
        list<vector<int>> l3 {{1,2,3},{4,5,6}, {7,8,9}};
        list<vector<string>> l4 {{"123", "234", "345"}, {"234", "345", "456"}};
        list<pair<int,int>> l5 {{1,2}, {2,3}, {3,4}};

        print(l1);
        print(l2);
        print(l3);
        print(l4);
        print(l5);
    }
    void test_deque () {
        deque<int> d1{1, 2, 3, 4, 5};
        deque<string> d2{"123", "234", "asd", "zxc"};
        deque<vector<int>> d3{{1, 2, 3},
                              {4, 5, 6},
                              {7, 8, 9}};
        deque<vector<string>> d4{{"123", "234", "345"},
                                 {"234", "345", "456"}};
        deque<pair<int, int>> d5{{1, 2},
                                 {2, 3},
                                 {3, 4}};

        print(d1);
        print(d2);
        print(d3);
        print(d4);
        print(d5);
    }
    void test_queue () {
        queue<int> q1;
        q1.push(1);
        q1.push(2);
        q1.push(4);
        q1.push(5);
        print(q1);
        print(q1);

        queue<pair<int,int>> q2;
        q2.push({2,3});
        q2.push({3,4});
        q2.push({5,7});
        q2.push({9,9});
        print(q2);
        print(q2);

        queue<string> q3;
        q3.push("123");
        q3.push("456");
        q3.push("asd");
        print(q3);
        print(q3);
    }
    void test_stack () {
        stack<int> stk1;
        stk1.push(1);
        stk1.push(2);
        stk1.push(3);
        stk1.push(4);
        print(stk1);
        print(stk1);

        stack<pair<int,int>> stk2;
        stk2.push({2,3});
        stk2.push({3,4});
        stk2.push({5,7});
        stk2.push({9,9});
        print(stk2);
        print(stk2);

        stack<string> stk3;
        stk3.push("123");
        stk3.push("456");
        stk3.push("asd");
        print(stk3);
        print(stk3);
    }
    void test_priority_queue () {
        priority_queue<int, vector<int>, greater<>> pq1;
        pq1.push(1);
        pq1.push(2);
        pq1.push(4);
        pq1.push(5);
        print(pq1);
        print(pq1);

        priority_queue<pair<int,int>> pq2;
        pq2.push({2,3});
        pq2.push({3,4});
        pq2.push({5,7});
        pq2.push({9,9});
        print(pq2);


        priority_queue<string> pq3;
        pq3.push("123");
        pq3.push("456");
        pq3.push("asdc");
        print(pq3);
        print(pq3);
    }
    void test_set () {
        set<int> s1 {1,1,2,2,3,3,4,4};
        set<pair<int,int>> s2 {{1,2},{2,3},{3,4},{1,2}};
        multiset<int> s3 {1,1,2,2,3,3,4,4};
        unordered_set<int> s4 {1,1,2,2,3,3,4,4};
        unordered_multiset<int> s5 {1,1,1,2,3,4,5,6};

        print(s1);
        print(s2);
        print(s3);
        print(s4);
        print(s5);
    }
    void test_map () {
        map<int,int> mp1 {{1,2},{2,3},{3,4}};
        map<string,string> mp2 {{"ad","da"}, {"cd", "sx"}};
        map<int, pair<int,int>> mp3 {{1, {2,3}}, {2, {3,3}}};
        map<int, vector<int>> mp4 {{1, {2,3}}, {3, {2,3}}};

        map<int, stack<int>> mp5;
        mp5[1].push(1);
        mp5[5].push(2);

        unordered_map<int, map<int,int>> mp6;
        mp6[1] = mp1;
        mp6[1000] = mp1;
        print(mp1);
        print(mp2);
        print(mp3);
        print(mp4);
        print(mp5);
        print(mp6);
    }
    void test() {
        test_vector();
        test_list();
        test_deque();
        test_queue();
        test_stack();
        test_priority_queue();
        test_set();
        test_map();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++中,遍历unordered_set容器有多种方法。下面是三种常见的方法: 方法一:使用迭代器进行遍历 可以使用迭代器来遍历unordered_set容器中的元素。例如,可以使用auto关键字来定义一个迭代器,并用begin()和end()函数获取unordered_set容器的起始和结束迭代器。然后,使用循环将迭代器逐个移动并输出元素。 示例代码如下: ``` std::unordered_set<std::string> uset{ "http://c.biancheng.net/c/", "http://c.biancheng.net/java/", "http://c.biancheng.net/linux/" }; for (auto iter = uset.begin(); iter != uset.end(); iter++) { std::cout << *iter << std::endl; } ``` 方法二:使用范围for循环遍历 使用C++11引入的范围for循环语法,可以更简洁地遍历unordered_set容器中的元素。在每次循环中,元素被自动赋值给循环变量,并可以直接输出。 示例代码如下: ``` std::unordered_set<std::string> uset{ "http://c.biancheng.net/c/", "http://c.biancheng.net/java/", "http://c.biancheng.net/linux/" }; for (const auto& element : uset) { std::cout << element << std::endl; } ``` 方法三:使用算法库函数进行遍历 可以使用算法库函数std::for_each来遍历unordered_set容器中的元素。该函数接受一个函数对象(或Lambda表达式)和容器的起始和结束迭代器,并将函数对象应用于每个元素。 示例代码如下: ``` #include <algorithm> void printElement(const std::string& element) { std::cout << element << std::endl; } std::unordered_set<std::string> uset{ "http://c.biancheng.net/c/", "http://c.biancheng.net/java/", "http://c.biancheng.net/linux/" }; std::for_each(uset.begin(), uset.end(), printElement); ``` 这样就可以使用上述三种方法之一来遍历unordered_set容器中的元素。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [STL无序容器之unordered_set和unordered_multiset](https://blog.csdn.net/andyjkt/article/details/116495385)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值