C++ 显示具有矢量的地图
C++ display map that has vector
std::map<std::string, std::vector<string>> data;
为了使用 copy
打印出来,我的 std::ostream_iterator
应该怎样?
显然 std::ostream_iterator<std::pair<std::string, std::vector<std::string>>> out_it(std::cout, "\n");
没有成功。
我的 operator<<
重载是下面的 std::ostream& operator<<(std::ostream& out, const std::pair<std::string, std::vector<std::string>>& p)
它写出了 p.first
和 p.second
和 returns 它。
这里是一个 operator<<
将从您的地图中打印出一对内容的方法:
std::ostream& operator<<(std::ostream& out, const std::pair<std::string, std::vector<std::string>>& p) {
out << p.first << ": "; // prints the string from key
for (const auto& i : p.second) // loops throught the whole vector that is asociated with that key
out << i << ", ";
return out;
}
所以在这个例子中使用它。如果您将此输入到您的地图中:
std::map<std::string, std::vector<string>> data;
std::vector<std::string> vec = {"VAL1", "VAL2", "VAL3"};
data.insert(std::make_pair("KEY", vec));
auto it = data.find("KEY");
std::cout << *it;
这将是使用上面的运算符<<打印出来的内容:
KEY: VAL1, VAL2, VAL3,
您还可以稍微更改一下格式,这样逗号也不会出现在最后一个值之后,但这只是一个外观问题。你的问题是你想在没有标准运算符<<的情况下打印矢量。因此,为了打印矢量,您必须手动循环遍历其内容,就像在我的示例中使用范围 for.
要自定义打印矢量,您必须自己编写一些代码。为确保使用您的自定义运算符,我建议您使用 std::stringstream
将键值对转换为字符串,然后将其输入 std::ostream_iterator<std::string>
.
某事,例如 this(请原谅 using namespace std;
):
#include <iostream>
#include <vector>
#include <string>
#include <iterator>
#include <algorithm>
#include <sstream>
#include <map>
using namespace std;
int main() {
map<string, vector<string>> m {
{"a", {"1", "2"}},
{"b", {"1", "2"}},
{"b", {"1", "2"}},
};
transform(begin(m), end(m), ostream_iterator<string>(cout), [](auto& p){
stringstream ss;
ss << p.first << ", {";
bool first = true;
for (auto& s : p.second)
{
ss << (first ? "" : ", ") << s;
first = false;
}
ss << "}\n";
return ss.str();
});
return 0;
}
我实际上并没有写 operator<<
,但你可以用你的替换来缩短 lambda 主体);
如果您使用 C++ 进行任何认真的编程,您最终将需要一种通用的方法来打印集合。
这是一个基础:
#include <iostream>
#include <map>
#include <vector>
#include <string>
// introduce the concept of an object that emits values to an ostream
// by default it simply calls operator <<
template<class T> struct emitter
{
using arg_type = T;
emitter(const T& v) : v_(v) {}
friend std::ostream& operator<<(std::ostream& os, const emitter& e) {
return os << e.v_;
}
const T& v_;
};
// introduce the concept of an io manipulator called emit
template<class T> auto emit(const T& v) -> emitter<T>
{
return emitter<std::decay_t<T>>(v);
}
// specialise the emitter for maps
template<class K, class V, class C, class A>
struct emitter<std::map<K, V, C, A>>
{
using arg_type = std::map<K, V, C, A>;
emitter(const arg_type& v) : v_(v) {}
friend std::ostream& operator<<(std::ostream& os, const emitter& e) {
const char* elem_sep = "\n\t";
const char* end_sep = " ";
os << "{";
for (const auto& elem : e.v_)
{
os << elem_sep << emit(elem.first) << ": " << emit(elem.second);
end_sep = "\n";
}
return os << end_sep << "}";
}
const arg_type& v_;
};
// specialise the emitter for vectors
template<class V, class A>
struct emitter<std::vector<V, A>>
{
using arg_type = std::vector<V, A>;
emitter(const arg_type& v) : v_(v) {}
friend std::ostream& operator<<(std::ostream& os, const emitter& e) {
const char* elem_sep = " ";
const char* end_sep = " ";
os << "[";
for (const auto& elem : e.v_)
{
os << elem_sep << emit(elem);
elem_sep = ", ";
}
return os << end_sep << "]";
}
const arg_type& v_;
};
int main() {
// build test data
std::map<std::string, std::vector<std::string>> data;
data.emplace("a", std::vector<std::string>{ "now", "is", "the", "time" });
data.emplace("b", std::vector<std::string>{ "for", "all", "good", "men" });
data.emplace("c", std::vector<std::string>{ "to", "come", "to", "the" });
data.emplace("d", std::vector<std::string>{ "aid", "of", "their", "party" });
// request an emitter manipulator
std::cout << emit(data) << std::endl;
}
预期输出:
{
a: [ now, is, the, time ]
b: [ for, all, good, men ]
c: [ to, come, to, the ]
d: [ aid, of, their, party ]
}
std::map<std::string, std::vector<string>> data;
为了使用 copy
打印出来,我的 std::ostream_iterator
应该怎样?
显然 std::ostream_iterator<std::pair<std::string, std::vector<std::string>>> out_it(std::cout, "\n");
没有成功。
我的 operator<<
重载是下面的 std::ostream& operator<<(std::ostream& out, const std::pair<std::string, std::vector<std::string>>& p)
它写出了 p.first
和 p.second
和 returns 它。
这里是一个 operator<<
将从您的地图中打印出一对内容的方法:
std::ostream& operator<<(std::ostream& out, const std::pair<std::string, std::vector<std::string>>& p) {
out << p.first << ": "; // prints the string from key
for (const auto& i : p.second) // loops throught the whole vector that is asociated with that key
out << i << ", ";
return out;
}
所以在这个例子中使用它。如果您将此输入到您的地图中:
std::map<std::string, std::vector<string>> data;
std::vector<std::string> vec = {"VAL1", "VAL2", "VAL3"};
data.insert(std::make_pair("KEY", vec));
auto it = data.find("KEY");
std::cout << *it;
这将是使用上面的运算符<<打印出来的内容:
KEY: VAL1, VAL2, VAL3,
您还可以稍微更改一下格式,这样逗号也不会出现在最后一个值之后,但这只是一个外观问题。你的问题是你想在没有标准运算符<<的情况下打印矢量。因此,为了打印矢量,您必须手动循环遍历其内容,就像在我的示例中使用范围 for.
要自定义打印矢量,您必须自己编写一些代码。为确保使用您的自定义运算符,我建议您使用 std::stringstream
将键值对转换为字符串,然后将其输入 std::ostream_iterator<std::string>
.
某事,例如 this(请原谅 using namespace std;
):
#include <iostream>
#include <vector>
#include <string>
#include <iterator>
#include <algorithm>
#include <sstream>
#include <map>
using namespace std;
int main() {
map<string, vector<string>> m {
{"a", {"1", "2"}},
{"b", {"1", "2"}},
{"b", {"1", "2"}},
};
transform(begin(m), end(m), ostream_iterator<string>(cout), [](auto& p){
stringstream ss;
ss << p.first << ", {";
bool first = true;
for (auto& s : p.second)
{
ss << (first ? "" : ", ") << s;
first = false;
}
ss << "}\n";
return ss.str();
});
return 0;
}
我实际上并没有写 operator<<
,但你可以用你的替换来缩短 lambda 主体);
如果您使用 C++ 进行任何认真的编程,您最终将需要一种通用的方法来打印集合。
这是一个基础:
#include <iostream>
#include <map>
#include <vector>
#include <string>
// introduce the concept of an object that emits values to an ostream
// by default it simply calls operator <<
template<class T> struct emitter
{
using arg_type = T;
emitter(const T& v) : v_(v) {}
friend std::ostream& operator<<(std::ostream& os, const emitter& e) {
return os << e.v_;
}
const T& v_;
};
// introduce the concept of an io manipulator called emit
template<class T> auto emit(const T& v) -> emitter<T>
{
return emitter<std::decay_t<T>>(v);
}
// specialise the emitter for maps
template<class K, class V, class C, class A>
struct emitter<std::map<K, V, C, A>>
{
using arg_type = std::map<K, V, C, A>;
emitter(const arg_type& v) : v_(v) {}
friend std::ostream& operator<<(std::ostream& os, const emitter& e) {
const char* elem_sep = "\n\t";
const char* end_sep = " ";
os << "{";
for (const auto& elem : e.v_)
{
os << elem_sep << emit(elem.first) << ": " << emit(elem.second);
end_sep = "\n";
}
return os << end_sep << "}";
}
const arg_type& v_;
};
// specialise the emitter for vectors
template<class V, class A>
struct emitter<std::vector<V, A>>
{
using arg_type = std::vector<V, A>;
emitter(const arg_type& v) : v_(v) {}
friend std::ostream& operator<<(std::ostream& os, const emitter& e) {
const char* elem_sep = " ";
const char* end_sep = " ";
os << "[";
for (const auto& elem : e.v_)
{
os << elem_sep << emit(elem);
elem_sep = ", ";
}
return os << end_sep << "]";
}
const arg_type& v_;
};
int main() {
// build test data
std::map<std::string, std::vector<std::string>> data;
data.emplace("a", std::vector<std::string>{ "now", "is", "the", "time" });
data.emplace("b", std::vector<std::string>{ "for", "all", "good", "men" });
data.emplace("c", std::vector<std::string>{ "to", "come", "to", "the" });
data.emplace("d", std::vector<std::string>{ "aid", "of", "their", "party" });
// request an emitter manipulator
std::cout << emit(data) << std::endl;
}
预期输出:
{
a: [ now, is, the, time ]
b: [ for, all, good, men ]
c: [ to, come, to, the ]
d: [ aid, of, their, party ]
}