Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: STL: set: stored value constness

Having the following code:

#include <iostream>
#include <set>
#include <string>
#include <functional>

using namespace std;

class Employee {
  // ...
  int _id;
  string _name;
  string _title;
public:
  Employee(int id): _id(id) {}

  string const &name() const { return _name; }
  void setName(string const &newName) { _name = newName; }

  string const &title() const { return _title; }
  void setTitle(string const &newTitle) { _title = newTitle; }

  int id() const { return _id; }
};

struct compEmployeesByID: public binary_function<Employee, Employee, bool> {
  bool operator()(Employee const &lhs, Employee const &rhs) {
    return lhs.id() < rhs.id();
  }
};

int wmain() {
  Employee emplArr[] = {0, 1, 2, 3, 4};
  set<Employee, compEmployeesByID> employees(emplArr, emplArr + sizeof emplArr/sizeof emplArr[0]);
  // ...
  set<Employee, compEmployeesByID>::iterator iter = employees.find(2);
  if (iter != employees.end())
    iter->setTitle("Supervisor");

  return 0;
}

I cannot compile this code having (MSVCPP 11.0):

1>  main.cpp
1>d:\docs\programming\test01\test01\main.cpp(40): error C2662: 'Employee::setTitle' : cannot convert 'this' pointer from 'const Employee' to 'Employee &'
1>          Conversion loses qualifiers

This helps to compile:

  if (iter != employees.end())
    const_cast<Employee &>(*iter).setTitle("Supervisor");

The question: I know that map and multimap store their values as pair(const K, V) where K is a key and V is a value. We cannot change the K object. But set<T> and multiset<T> store their object as T, not as const T. So WHY I NEED THIS CONST CAST??

like image 780
nickolay Avatar asked Dec 03 '22 00:12

nickolay


1 Answers

In C++11 set (and multiset) specify that iterator as well as const_iterator is a constant iterator, i.e. you cannot use it to modify the key. This is because any modification of they key risks breaking the set's invariant. (See 23.2.4/6.)

Your const_cast opens the door to undefined behaviour.

like image 118
Alan Stokes Avatar answered Dec 07 '22 23:12

Alan Stokes