3

I have a C++ std::map that I'm using to store information about connected components. Here's the segment of code from my BaseStation class, it's very basic

//Constructor
BaseStation(string name, int x, int y){
    id = name;
    xpos = x;
    ypos = y;
}

//Accessors
string getName(){
    return id;
}

In my main code, I have a map declared as

map<BaseStation, vector<string> > connection_map;

The connection_map is updated in a while loop as follows, and then for my own debugging purposes I want to dump the contents of the map. I append a BaseStation object to the map (as the key) and as the value we have the list of links to the BaseStation object:

connection_map[BaseStation(station_name, x, y)] = list_of_links; 
list_of_links.clear();

for(auto ptr = connection_map.begin(); ptr != connection_map.end(); ++ptr){
    cout << ptr->first.getName() << " has the following list: ";
    vector<string> list = ptr->second;
    for(int i = 0; i < list.size(); i++){
        cout << list[i] << " ";
    }
    cout << endl;
}

This is the error I get in my main when I try to compile my code via clang++:

server.cpp:66:11: error: 'this' argument to member function 'getName' has type
  'const BaseStation', but function is not marked const
            cout << ptr->first.getName() << " has the following list: ";

and in VSCode, the tooltip highlight at the cout (cout << ptr->first.getName()) is the following:

the object has type qualifiers that are not compatible with the member 
function "BaseStation::getName" -- object type is: const BaseStation

I don't understand what's going on, as the getName() function is most definitely not constant, and nowhere do I declare my BaseStation object as const either. If someone could help me out that would be great. Thanks!

danielschnoll
  • 3,045
  • 5
  • 23
  • 34
  • 4
    change to `string getName() const { return id; }` – M.M Nov 12 '19 at 02:02
  • @M.M, it will be better to return `const string&` instead of `string` for better optimisation without relying on compiler. – iammilind Nov 12 '19 at 02:19
  • @iammilind disagree as that can introduce dangling references. It could perhaps return a `string_view` – M.M Nov 12 '19 at 02:25
  • @M.M, `string_view` seems for C++17 or later. I am unable to see any issue in return by const reference. It will be helpful, should you give a code example demonstrating the "dangling reference" issue? – iammilind Nov 12 '19 at 02:30
  • @iammilind [see here](https://stackoverflow.com/a/134777/1505939) – M.M Nov 12 '19 at 02:33
  • @M.M, that's not a real world problem. No sane coder deletes a pointer/reference in the same function. Yes, it's a coding problem, but it can also happen when the pointer is returned. – iammilind Nov 12 '19 at 04:07
  • @iammilind it is not uncommon to write something like `const string& foo = bar().get_name();` – M.M Nov 12 '19 at 08:49

1 Answers1

5

std::map stores the key as const.

value_type std::pair<const Key, T>

That means when you get the key from map (like ptr->first), you'll get a const BaseStation.

I think you should declare BaseStation::getName() as const member function, since it's not supposed to perform modification.

songyuanyao
  • 169,198
  • 16
  • 310
  • 405