4

次のコードを持つ:

#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;
}

(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

これはコンパイルに役立ちます:

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

質問: 私はそれを知ってmapおり、multimapそれらの値を次のように保存しますpair(const K, V)。ここで、K はキー、V は値です。K オブジェクトを変更することはできません。しかしset<T>、オブジェクトをではなく としてmultiset<T>保存します。では、なぜこの const キャストが必要なのですか??Tconst T

4

4 に答える 4

4

a の値はset変更されるべきではありません。たとえば、従業員 ID を変更すると、セット内の間違った位置に配置され、セットが破損します。

Employee には 3 つのフィールドがあり、セットは _id フィールドを使用していますoperator<

class Employee {
  // ...
  int _id;
  string _name;
  string _title;

};

したがって、map<int,Employee>セットの代わりに a を使用すると、名前とタイトルを変更できるようになります。_idEmployeeのフィールドも にしconst int _idます。

(ちなみに、 で始まる識別子_は技術的に予約されているため、避ける必要があります。これで問題が発生することはありませんが、変数名の末尾にアンダースコアを付けるようになりました。)

于 2012-01-16T22:45:39.883 に答える
0

const間接化だけで逃げることができます。

ただし、特定のソート済みコンテナー内の要素の順序を変更しないように注意してください。

于 2012-07-21T02:04:54.957 に答える