如何在C++中打印通用地图

如何在C++中打印通用地图,c++,templates,C++,Templates,我试图写一个函数来打印通用映射。 这就是我到目前为止所做的: template<typename map_key, typename map_val> void log(DEBUG_LEVEL level, std::map<map_key, map_val> _map) { if (level >= d_level) { for (std::map<map_key, map_val>::itera

我试图写一个函数来打印通用映射。 这就是我到目前为止所做的:

    template<typename map_key, typename map_val>
    void log(DEBUG_LEVEL level, std::map<map_key, map_val> _map) {
        if (level >= d_level) {
            for (std::map<map_key, map_val>::iterator it = _map.begin();
                    it != _map.end(); ++it)
                std::cout << it->first << " => " << it->second << '\n';
        }
    }
为什么这不是编译? 有没有更好的方法写这个?我在第二个答案中找到了一条打印向量的单行线,我想知道地图上是否也有同样的答案? 更新:我修复了1,但仍在等待2的答案 我喜欢Galik的答案,但当我尝试将其作为函数添加时,我遇到了一个错误:错误:'std::ostream&Logger::operatortypename丢失。 应该是

template<typename map_key, typename map_val>
void log(DEBUG_LEVEL level, const std::map<map_key, map_val>& _map) {
    if (level >= d_level) {
        for (typename std::map<map_key, map_val>::const_iterator it = _map.begin(); it != _map.end(); ++it)
            std::cout << it->first << " => " << it->second << '\n';
    }
}
或者在C++11中

template<typename map_key, typename map_val>
void log(DEBUG_LEVEL level, const std::map<map_key, map_val>& _map) {
    if (level >= d_level) {
        for (const auto& p : _map)
            std::cout << p.first << " => " << p.second << '\n';
    }
}

在回答你的第二个问题时,你可以考虑更通用,允许更多不同类型的容器。

比如:

#include <map>
#include <set>
#include <vector>
#include <iostream>

typedef int DEBUG_LEVEL;
int d_level = 0;

template<typename Key, typename Value>
std::ostream& operator<<(std::ostream& os, const std::pair<const Key, Value>& p)
{
    os << p.first << " => " << p.second;
    return os;
}

template<typename Container>
void log(DEBUG_LEVEL level, const Container& c) {
    if (level >= d_level) {
        for(typename Container::const_iterator it = c.begin();
            it != c.end(); ++it)
        std::cout << *it << '\n';
    }
}

// OPTIONAL Adding your own types

class MyClass
{
    int i;
    std::string s;
public:
    MyClass(int i, std::string s): i(i), s(s) {}

    // declare the operator<<() overload as a friend to grant access
    // to private members
    friend std::ostream& operator<<(std::ostream& os, const MyClass& mc);

};

// define the operator<<() for MyClass as a global function (required)
std::ostream& operator<<(std::ostream& os, const MyClass& mc)
{
    os << "{MyClass: " << mc.s << ": " << mc.i << "}";
    return os;
}


// End of OPTIONAL

int main()
{
    std::set<int> s;
    s.insert(6);
    s.insert(3);
    s.insert(4);

    std::map<int, int> m;// {{1, 2}, {3, 4}};
    m[1] = 2;
    m[3] = 4;

    std::vector<int> v;
    v.push_back(4);
    v.push_back(3);
    v.push_back(2);
    v.push_back(1);

    std::cout << "\nset:\n";
    log(1, s);

    std::cout << "\nmap:\n";
    log(1, m);

    std::cout << "\nvector:\n";
    log(1, v);

    std::cout << "\nvector of MyClass:\n";
    std::vector<MyClass> vmc;
    vmc.push_back(MyClass(1, "hello"));
    vmc.push_back(MyClass(2, "world"));

    log(1, vmc);
}

可能希望通过常量引用传递映射,如void logDEBUG_LEVEL、const std::map和_map,因为您没有更改它,而且它可能很大。缺少typename,在C++11中,只需为const auto&p执行以下操作:_map{std::cout甚至模板void logDEBUG_LEVEL、const map&map{…}@MichaelAnderson:它不是等价的,比如OP可能也想为std::vector编写重载,但它更简单,可能就足够了。当用坏类型调用它时,错误消息会更混乱。是的,它肯定有它的优点和缺点。例如,如果你切换到散列映射或无序映射或其他类型,它会工作。但是c会吗如果你给它传递一个向量,我会以一种毫无帮助的方式进行omplain…我喜欢这个答案,但是-如何将这些函数添加到类中?我有一个Logger类,我希望这些方法在其中。当我试图将过去的函数复制到我的类中时,我得到了下一个错误:“error:'std::ostream&Logger:”operator@yehudahs你不能把这个operator@yehudahs我补充说示例的可选部分显示如何将自己的类添加到输出中。
template<typename map_key, typename map_val>
void log(DEBUG_LEVEL level, const std::map<map_key, map_val>& _map) {
    if (level >= d_level) {
        for (const auto& p : _map)
            std::cout << p.first << " => " << p.second << '\n';
    }
}
#include <map>
#include <set>
#include <vector>
#include <iostream>

typedef int DEBUG_LEVEL;
int d_level = 0;

template<typename Key, typename Value>
std::ostream& operator<<(std::ostream& os, const std::pair<const Key, Value>& p)
{
    os << p.first << " => " << p.second;
    return os;
}

template<typename Container>
void log(DEBUG_LEVEL level, const Container& c) {
    if (level >= d_level) {
        for(typename Container::const_iterator it = c.begin();
            it != c.end(); ++it)
        std::cout << *it << '\n';
    }
}

// OPTIONAL Adding your own types

class MyClass
{
    int i;
    std::string s;
public:
    MyClass(int i, std::string s): i(i), s(s) {}

    // declare the operator<<() overload as a friend to grant access
    // to private members
    friend std::ostream& operator<<(std::ostream& os, const MyClass& mc);

};

// define the operator<<() for MyClass as a global function (required)
std::ostream& operator<<(std::ostream& os, const MyClass& mc)
{
    os << "{MyClass: " << mc.s << ": " << mc.i << "}";
    return os;
}


// End of OPTIONAL

int main()
{
    std::set<int> s;
    s.insert(6);
    s.insert(3);
    s.insert(4);

    std::map<int, int> m;// {{1, 2}, {3, 4}};
    m[1] = 2;
    m[3] = 4;

    std::vector<int> v;
    v.push_back(4);
    v.push_back(3);
    v.push_back(2);
    v.push_back(1);

    std::cout << "\nset:\n";
    log(1, s);

    std::cout << "\nmap:\n";
    log(1, m);

    std::cout << "\nvector:\n";
    log(1, v);

    std::cout << "\nvector of MyClass:\n";
    std::vector<MyClass> vmc;
    vmc.push_back(MyClass(1, "hello"));
    vmc.push_back(MyClass(2, "world"));

    log(1, vmc);
}
set:
3
4
6

map:
1 => 2
3 => 4

vector:
4
3
2
1

vector of MyClass:
{MyClass: hello: 1}
{MyClass: world: 2}