Home > Mobile >  Getting an error while using nested STL map
Getting an error while using nested STL map

Time:05-02

Given this code:

map<int,multiset<string>,greater<int>> m;
int n;
cin>>n;

for(int i=0;i<n;i  ){
    string s;
    int x;
    cin>>s>>x;
    m[x].insert(s);
}

for(auto &it:m){
    cout<<it.second<<" "<<it.first<<endl;
}

Can anyone explain to me why I am getting an error in it.second part ? The error is: no operator "<<" matches these operands.

CodePudding user response:

The "second" part of the std::map is a std::multiset. And this

  • has no overload for the insert operator <<
  • and can contain multiple elements

What should << do with the multiset?.

What you need to do is to add a second loop, that outputs the values of the std::multiset.

Something like:

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

int main() {

    std::map<int, std::multiset<std::string>, std::greater<int>> m;
    int n;
    std::cin >> n;

    for (int i = 0; i < n; i  ) {
        std::string s;
        int x;
        std::cin >> s >> x;
        m[x].insert(s);
    }

    for (auto& it : m) {
        for (auto& sec : it.second)
            std::cout << sec << " " << it.first << '\n';
        std::cout << "\n\n";
    }
}

But also this does not make that much sense, since, as said, a std::multiset can contain more than one value.

And you assign always only one value, so, a multiset with on value, to a key of the map. You could comit the complete std::multiset in your example.

But maybe you will siggn more values later. Then my code snippet would make sense.

CodePudding user response:

it.second refers to a multiset<string...>, passed to std::cout. There just is no operator<< defined for that type, as the message says, that's why you get the error message. That operator is required for std::cout to be able to output the given thing. It's only predefined for std::string, the basic types (int, float, ...) and maybe a few other basic classes, but not for a std::multiset.

It is not predefined because there might be things that everyone having such a multiset might do differently, such as how the operator<< should deal with its multiple elements it can contain (separate them with space, comma, ...?). In the below code, we don't separate them at all, since there's only one element in there yet anyway.

You would need to overload operator<< for that type, something like:

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

template <class T, class U>
std::ostream& operator<<(std::ostream& out, std::multiset<T, U>& c)
{
        for (auto e: c)
        {
                out << e;
        }
        return out;
}

int main()
{
        std::map<int,std::multiset<std::string>, std::greater<int>> m;
        int n;
        std::cin>>n;

        for(int i=0;i<n;i  ){
            std::string s;
            int x;
            std::cin>>s>>x;
            m[x].insert(s);
        }

        for(auto it: m){
            std::cout<<it.second<<" "<<it.first<<std::endl;
        }
}
  • Related