C ++显示有矢量的地图

时间:2016-12-12 09:17:58

标签: c++ string vector std-pair

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.firstp.second并将其返回。

3 个答案:

答案 0 :(得分:3)

如果你在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 ]
}

答案 1 :(得分:1)

所以这是一个with tmp1 as ( select row_number() over(order by (select null) ) - 1 newid , (row_number() over(order by (select null)) - 1) %12 rg1 , f1.* from table2 f1 ), tableranked as ( select DENSE_RANK() over(partition by rg1 order by newid) rg2, f2.* from tmp1 f2 ) select f1.id, f1.date, f4.date1, f4.date2 from tableranked f1 inner join (select f2.id, f2.date as date1, f3.date as date2 , f2.rg1 from tableranked f2 inner join tableranked f3 on f2.id=f3.id and f2.rg2+1=f3.rg2 and f2.rg1=f3.rg1 where f2.newid>=12 and f3.newid>=12 ) f4 on f1.id=f4.id and f1.rg1=f4.rg1 where f1.newid<12 ,它会打印出地图中一对的内容:

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;
}

这将是使用运算符打印出来的&lt;&lt;以上:

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;

您还可以稍微更改格式,以便逗号不在最后一个值之后,但这只是一个整容问题。你的问题是你想要打印矢量,而它没有标准运算符&lt;&lt;。因此,为了打印矢量,你必须手动循环它的内容,就像在我的例子中使用ranged for。

答案 2 :(得分:0)

要自定义打印矢量,您必须自己编写一些代码。为确保使用自定义运算符,建议您使用std::ostream_iterator<std::string>将键值对转换为字符串,然后将其输入using namespace std;

某些内容,例如this(请原谅#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<<

我实际上并没有写var url = "https://1.bp.blogspot.com/-5MNg6YxqvVA/WEfPc3ZooiI/AAAAAAAAIGU/k54H_HugZbkw9KIo56UjksgiVkX7b-mhACLcB/s540/antipasto-salad-21354_l.jpeg"; ,但你可以替换你的lambda身体短路;