1
votes

I have a class defined as follows in the .h:

#ifndef C1_H
#define C1_H

#include <iostream>
#include <map>
#include <string>
#include <vector>

class C1{
        private:
                std::map<std::string, std::vector<int>> cmap;
        public:
                C1();
                ~C1();
                friend std::ostream& operator<< (std::ostream& os, const C1& c);
};

#endif

I am having trouble with the output stream function. In the cpp file, I have it defined as:

ostream& operator<< (ostream& os, const C1& c) {
        vector<string> strlist= //a vector of the strings associated in the map;
        cout << *(strlist.begin()+3) << endl; //this was for testing where the error was
        for (int j = 0; j < 9; j++) {
                int size = c.cmap[*(strlist.begin() + j)].size();
                for (int k = 0; k < size; k++) {
                        os << (c.cmap[*(strlist.begin()+j)]].[begin()+k])<<endl;
                }
        }
        return os;
}

But get the following error: error: passing ‘const std::map,

error: passing ‘const std::map, std::vector >’ as ‘this’ argument of ‘std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = std::basic_string; _Tp = std::vector; _Compare = std::less >; _Alloc = std::allocator, std::vector > >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = std::vector; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = std::basic_string]’ discards qualifiers [-fpermissive] int size = t.tokenmap[*(type.begin() + j)].size();

This compiles fine when I remove the const protection from the definitions of the ostream operator overload, however, I believe I should be able to do it with the const protection, and according to my teacher it is much better practice to get in the habit of it now. Can anybody guide me in the direction as to why this does not compile?

I would have though that, since the ostream is a friend class, I would be able to access the private members (like usual, I use this same basic structure for most of my operator<< overloads and access private members all the time) but I am assuming the issue has to do with the fact that there is a vector inside of the const protected object that may also somehow be const protected (just a thought... I've never overloaded << with a map, so this is new to me), leading to the qualifier issue. I would love to hear any suggestions you guys may have, as I really want to do this with the const protection instead of just discarding it. Thanks in advance!

1
std::map's operator [] is non-const since it inserts an element if the key doesn't exist.T.C.

1 Answers

1
votes

In:

int size = c.cmap[*(strlist.begin() + j)].size();

you should write:

int size = c.cmap.at(*(strlist.begin() + j)).size();

instead.

You are passing c as const C1&, which means that c.cmap is also const.

std::map has no const overload for operator[], because operator[] performs an insertion if the key does not exist. This is in order to make statements like:

std::map<std::string, int> map;
map["test"] = 1;

work.