C++:STL:set:存储值constness

Dad*_*dyM 4 c++ stl const invariants set

拥有以下代码:

#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;
}
Run Code Online (Sandbox Code Playgroud)

我无法编译此代码(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
Run Code Online (Sandbox Code Playgroud)

这有助于编译:

  if (iter != employees.end())
    const_cast<Employee &>(*iter).setTitle("Supervisor");
Run Code Online (Sandbox Code Playgroud)

问题:我知道,mapmultimap存储他们的值pair(const K, V),其中K是一个关键,V是一个值.我们无法改变K对象.但set<T>multiset<T>他们的对象存储为T,不作为const T.那么为什么我需要这个CONST CAST?

Ala*_*kes 12

在C++ 11集(和多集)指定iterator以及const_iterator是一个常量迭代器,也就是说你不能用它来修改的关键.这是因为它们的任何修改都会破坏集合的不变性.(见23.2.4/6)

const_cast打开未定义行为的大门.