如何在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}