我的地图声明如下:
map < string, set<string> > index;
std::map < string, set<string> >::iterator iter;
我想打印index
的内容。因此,我写了以下内容:
for (iter = index.begin(); iter!= index.end(); iter++){
cout << iter->first << endl;} // It's OK.
但是如果我尝试打印iter->second
:
for (iter = index.begin(); iter!= index.end(); iter++){
cout << iter-> second << endl;} // Doesn't work.
我想这是因为second
中的index
是一组字符串而不是简单的字符串。但是我怎么能打印出来呢?
答案 0 :(得分:3)
如果要打印
iter->second
使用运算符&lt;&lt;,您必须覆盖此运算符!否则,使用set迭代器迭代iter-&gt; second rappresent的字符串集:
set<string>::iterator iterator_;
迭代很容易,忍者解决方案是重载运算符! :P
迭代:
map<string, set<string> >::iterator iter_;
for (iter_ = index_.begin(); iter_ != index_.end(); iter_++) {
cout << iter_->first << " - ";
set<string>::iterator iterator_;
for (iterator_ = s.begin(); iterator_ != s.end(); iterator_++) {
cout << *iterator_ << " - ";
}
cout << endl;
}
class MySet: public set<string> {
friend ostream& operator<<(ostream& out, const MySet& s) {
set<string>::iterator iterator_;
for (iterator_ = s.begin(); iterator_ != s.end(); iterator_++) {
out << *iterator_;
}
return out;
}
void test() {
map<string, MySet> index_;
map<string, MySet>::iterator iter_;
for (iter_ = index_.begin(); iter_ != index_.end(); iter_++) {
cout << iter_->first << " - ";
cout << iter_->second;
}
}
};
答案 1 :(得分:1)
过去几年我使用了以下功能。如果重载operator&lt;&lt ;,那么你必须要小心,因为你最终会得到错误,因为它无法在标准运算符&lt;&lt;之间进行选择。和您的自定义运算符&lt;&lt;。
随着C ++ 11引入lambdas和基于范围的for循环,我可能不太经常需要它。
#include <vector>
#include <iostream>
#include <algorithm>
#include <iterator>
using namespace std;
template<typename C>
void print_container(ostream& os, const C& c)
{
copy(c.begin(), c.end(), ostream_iterator<int>(os, " "));
}
int main(void)
{
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
print_container(v);
}
答案 2 :(得分:0)
(在我看来)C ++中最烦人的事情是没有为标准库类型定义输出运算符。
你需要一些代码:
typedef std::map < string, set<string> >::iterator iter;
for (iter = index.begin(); iter!= index.end(); iter++) {
std::cout << iter->first << " : {";
for(set<string>::iterator it = iter->second.begin(); it != iter->second.end(); ++it) {
std::cout << *it << " ";
}
std::cout << "}\n";
}
答案 3 :(得分:0)
如您所说,iter->second
代表代码中的一组字符串。您不能简单地打印它,因为输出流的operator<<
不知道默认情况下如何格式化std::set
。如 Luca Davanzo's answer所述,一种解决方案是为该集合重载该运算符。
另一种解决方案(如 Chris Jefferson的 answer所示)是简单地添加另一个循环以遍历您的集合。但是,可以使用以下C++11功能:range-based for loops和占位符auto来提高该解决方案的可读性。结果,您的代码可能看起来很简短:
std::map<std::string, std::set<std::string>> index;
index["a"] = { "v", "w" };
index["b"] = { "x", "y", "z" };
for (const auto &mapItem : index) {
std::cout << "m[" << mapItem.first << "] =";
for (const auto &setItem : mapItem.second)
std::cout << " " << setItem;
std::cout << std::endl;
}
输出:
m [a] = v w
m [b] = x y z
自C++17起,您可以与structured bindings一起使用基于范围的for循环。由于您可以从代码中删除first
和second
成员,因此进一步提高了可读性:
for (const auto &[k, v] : index) {
std::cout << "m[" << k << "] =";
for (const auto &s : v)
std::cout << " " << s;
std::cout << std::endl;
}